It's 2022 and front-end is still a mess

This is just a short rant I guess. Recently, I've wanted to work on some projects requiring me to write a web front-end and every time I revisit doing this, I'm left feeling very frustrated and defeated.


I actually like front-end

Not something you normally hear from people that spend their time writing deploy pipelines and VPC network infrastructure. I've always liked the creative aspect of web design and working on visual mediums. At one point I thought I'd be doing front end dev, but quickly decided to not pursue it after working on front-end stuff at Carfax for about a year. 

 

At that time, front-end was mostly dominated by jQuery plugins and crazy over-engineered MVC frameworks. Around this time, Bootstrap was released, along with a bunch of other CSS / JS frameworks that were supposed to help make development faster. They kind of did, but also introduced a lot of issues with customizing things to your needs that you were probably better off writing your own library for you own needs. 

I left front-end dev because of just how painful it was to do, and it has always felt so needlessly difficult. Like how many of us have had the experience of "how do I center this fuckin div!". Why is that so hard? Back then we only aligned stuff using floats or tables. I guess in short, the web was just too immature and clunky to my liking. Even today, I feel like you have to be something of a masochist to actually want to do front-end.

As a programmer, I thoroughly enjoy the fact that other people write high quality libraries so that I can just reuse their code and not have to think about those problems and just get going with my project. This is true for most things I do with DevOps and backend libraries in Python. Those libraries / tools work great most of the time. I really wish I could say the same for the frontend...


How it feels to do front-end in 2022

You have a new project and your colleague told you that React is good and an industry standard. So you spend the next hour just trying to choose one out of literally thousands of component libraries to use. 

After you spend an hour waiting for NPM to finish installing the 200mb of needed NodeJS packages, and you finished reading for another hour on Webpack docs so that you can have a constantly running build pipeline locally because this framework uses MochaScript; a way "better" version of JavaScript apparently that has to be compiled. Now you can finally start a local webserver with the convenient and never broken npm start dev command!

If by some miracle you get that working in less than a half day, now you get finally use these components! Wait, the docs don't have copy and passable code? It's no problem; you just have to dig through lots of stack overflow posts to find an example that you can tailor to your needs.

I for one am glad that the frontend community adheres to common conventions. After all; what really is the semantic difference between a Modal, Dialog, Popup and Popover.

So after a while of thoroughly reading the docs and StackOverflow, you finally figured out what to do. You start writing your app, and get pretty far. Ah but your compontent library is missing a component that you need.

Do you...

  • Switch to a new component library and rewrite everything from scratch?
  • Try to import just the components you need and make a frakenframework of sorts?
  • Write your own component?

Writing your own component is sooooo easy. Just use this code generator that will make 30 files for you, and be sure to be up to date on the latest JavaScript, React, JSX and CSS features otherwise you'll be completely lost.

Wait none of that matters now; a new thing came out this week!

The library you using has decided to completely switch underlying tools and dependencies, now you have to decide if you will update to this standard; and they gave you 1 week notice of this change. Most of the code you wrote will have to be significantly changed and the old version of this framework becomes effectively abandoned so you never get updates or security patches. Foolish mortal; you thought MochaScript was the perfect JavaScript? Behold CoffeeScript! Its like MochaScript, but slower and with questionable syntactic sugar.

 

exampleCode().
  showing(aThing(), thisLibrary.does())
  .justIgnore(
    () -> theSyntax()
);

So readable.

Thank goodness they added these chained call backs, I don't know how people coded before this! I hope I don't have issues compiling back to ES6. Don't sweat it too much though, wait another few months and they'll be using MelonScript or SuperScript, or some new flavor that will solve all it's problems. 

Now your app has been in production for a few months and you need to fix some bugs; requiring you to update your library version. Well now you can't even do that because the package maintainer took the library off the internet and replaced it with bitcoin mining software to protest Climate Change.


Roasting Javascript Aside...

I admit that these issues are not exclusive to JavaScript / Frontend dev. Though it feels especially bad in frontend because of how quickly things are changing. And to what end? Sometimes I really wonder; have we not found the right abstractions to write engaging and pretty user interfaces? Why is it this difficult just to get a basic dynamic page working?

And for fuck sake, can we get a language other than JavaScript to use on the frontend? A lot of these "JavaScript but better" languages that require transpilers have sprung up to attempt to fix the issues with JavaScript itself, which is sort of an interesting way to test new language features and ideas; but good lord JavaScript has the highest density of footgun's of any language I've ever used. I'm sure the reason they don't just make JavaScript not full of foot guns is that they are trying to maintain reverse compatibility.

I know that WebASM is supposed to be at some point allow us to solve this issue of a single language dominating the front-end, but we really haven't seen much practical things from that effort yet; outside of cool OpenGL ports.

I loved the simplicity of the old web. You can super quickly prototype something on a local web page. You didn't need to worry about package managers, CDN's, or running a web server. 

From a DevOps perspective; I will go very very very far out of my way to not have to run a production NodeJs server. I've had numerous horrendous experiences in managing and troubleshooting production NodeJs servers. I'd much rather stick with the devil I know, like NginX. Again I yearn for the simpler times when you just served an HTML page and didn't have so much complexity to deal with. Browser default components don't have any of these issues, why can't we have more of those?

I've been following the evolution of front-end for a long time. I don't think front-end developers realize just how complex they have made their ecosystem. And I'd say, quite needlessly so. For something as huge as Facebook, that level of complexity is probably warranted; but the level of complexity that Facebook uses is the only level. React is React. There is not really a lower level of complexity for smaller teams or hobby projects. One that doesn't require WebPack, NodeJS server, JestJs tests, code generation, tree shaking, CSS precompliation, etc etc. One where you can just get to the heart of what you're actually trying to do, which is make a fucking usable component.


Web Components?

The thing that I think frameworks like React get right is the component encapsulation model and in principal I quite like the React way of doing this, it's just all the ecosystem surrounding it that is really painful and a huge turn off to me and the tools are individually so complex and never work out of the box for me.

When React rose to popularity in ~2015 (which is right around the time when I left Carfax and moved on to DevOps) the W3C had been working to develop and implement a way to do what React does, natively in the browser. 

This is usually referred to as Web Components; but is really the combination of 3 features to the web standard:

  • Custom Elements
  • Shadow DOM
  • HTML Templates and Slots

I quite like the idea of having these things natively. It gives me the thing that I want which is ease of development. I don't need build frameworks, or Webpack or tree shakers or anything like that. All you need to do is include a JavaScript file on your page and you're done. This seems like the level of complexity I'm looking for.

As of 2018, all major browsers support all three of these standards natively which means that native custom components have arrived.


Authoring Web Components

These native API's are a bit clunky to use, or should I say are low level. It makes sense, to a degree, that they would do it that way because it allows for libraries to sit on top that expose different abstractions tailored to certain needs. But I fear this gets us back to the issues from before where these libraries will bring in elaborate build systems and complex bundlers and such.

With that said, I've experimented with a few libraries, as well as 

I quite like Stencil, but am a bit annoyed that it forces you to exclusively use Typescript. It is essentially a toolchain for "compiling" Typescript as well as the HTML and CSS into a native web component. The thing I like the most about it is that it includes the primitives for hydration and minifying bundles. I could use this tool right out of the box. Or put another way; you can experience success in 5 minutes with this tool; which is more than can be said about React. However, in general, I'm quite wary of complex build chains, and indeed if there was some kind of underlying problem with Stencil's use of WebPack, I'd be at a complete loss at how to fix it.

I also quite like Lit, though it doesn't come with all the same nice batteries that Stencil does. Normally this would be a trade off of bundle size but infact Stencil and Lit will produce bundles of basically the same size since they will both produce an artifact that is just the native component with a thin abstraction layer over it. Though all I really care about for small projects is just being able to author a component quickly. Lit is basically just a thin abstraction on top of the native API's. I won't really know which of these I prefer until I really dig into a project using them.


Native Component Libraries

I've searched pretty thoroughly across the web for anyone authoring native web components and here's all the ones I've found:

I've dabbled with all of these, and the one I like the most is Shoelace. It seems to be the most batteries included, but also customizable (via "design tokens") of the lot.

To me these are basically the next evolution of Bootstrap. Gives you a lot of stuff out of the box, but this much less boilerplate-y to use, and has the styles encapsulated. 

For some upcoming projects; I think I will likely make use of Shoelace and then use Lit or Stencil to author custom components that suit my specific needs, and then glue component functionality together with plain old fashioned no frills JavaScript.


Things do seem to be getting better

With the advent of native web components alongside tons of fantastic new CSS features such as Grid, Flexbox, and variables, it seems like things are heading in a good direction for the web. 

Right now I'm just stuck in a bit of a limbo waiting for Web Components and WebASM to really get mainstream adoption and start bearing fruit. React just has so much momentum and adoption that these new standards will take a while to get large scale adoption.

 

Though one very nice feature of native components is that you can just use them in React, Vue, Angular, Svelte and basically every React-like framework; so there is a non destruction path to adoption at least.

At least with native web components, we can rely on them to work basically forever. One of my biggest gripes is that with all the frameworks and libraries out there; how many times has someone reinvented the "button" component? There may be times that this needs some specific customized button; but generally its just a box with text. My hope is that native web components will see a lot of reduction of this reinventing the wheel. Just a handful of libraries that give us the tools to customize parts of the element as we need and we're off to the races; or hell, give me high quality, accessible but otherwise unstyled components that I can customize to my brand / needs.

My hope is that one day, the web wont be so painful that I might be able to re-enter the world of the front-end as a professional. For now, I'm fine to watch from the sidelines.