Front-end is a cornucopia of bad ideas. It’s full of frameworks, patterns, and technologies that make your job harder, not easier. Over the years, I have realized the hardest thing about front-end is picking up the pieces that “just work” and ignoring the noise. Unfortunately, you don’t always have a choice.
Caution: Strong opinions follow. If these things work for you, then great. But, generally, I have seen them creating problems not solving them.
Take a look at styled-components. It’s a CSS-in-JS library that’s extremely popular for styling React components. It involves defining CSS within the React component, which is then compiled into scoped CSS.
It’s hard to overstate how terrible this pattern is. But the frontend world eats it up like it’s the most natural consequence of architecting components. It makes it absurdly difficult to share common styles across components. It makes the code verbose. And because we do away with helpful class names, it becomes impossible to map the output to your code. You spend half your time trying to understand where the styles are coming from. Advanced features like composition of styles is almost never useful and create more problems than they solve.
Then there’s Redux. Okay, I give credit to React team for figuring out a good pattern to model front-end. I am old enough to remember the MVC madness around 2010-14. But why is it so complicated? If you’ve figured out the view layer, you just need a way to sync data with it. Why do I need to juggle actions, reducers, five different files, and multiple constants, just to update a single field? Don’t tell me it’s necessary to avoid problems in the future! Simple ideas and common sense go way further than purists would claim.
Don’t even get me started on Bundlers. I thought Webpack was complex, so I started trying something simpler. Parcel looked good, until one day I needed my bundled file to be of a different name than the source file. Turns out that until very recently it wasn’t even possible. Even now it’s only possible by writing a plugin and adding
.parcelrc. Seriously, how hard could be to add a CLI param
Thought rollup might be better. But that doesn’t support “require.” So any dependency you add that uses CommonJS syntax, you’re out of luck. But, of course, you can. You just need to use a plugin for that. It doesn’t even support third-party NPM modules without another plugin. And I am not alone who found it frustrating.
Sometimes, I find it easier to hook up tools like browserify, minify to do what I want.
Why do I have to struggle so much to find good tools? Why is front-end full of anti-patterns? Why dev’s experience is never a priority?
It’s amazing how difficult writing good front-end has become. The hard part isn’t getting something done, it’s almost always how do I fight against the framework/approach to do it. Ultimately, the code becomes garbage like everyone else’s. Even though most would hate to admit it, it’s evident from how much of a headache trivial tasks can become. Sadly, front-end devs never realize there could be a better way to get things done.
There’s a glimmer of hope though. There are well-run projects that focus on making a dev’s life easier. Thanks to them, I have been able to preserve my sanity:
TailwindCSS: Besides the fact that Tailwind will significantly reduce the overhead of styling your app/website, I just love how dedicated authors are towards making it as easy to use as possible. There are only a few concepts to be understood to get started and it scales incredibly well to fit any use case. I do think some of its users go overboard with the idea and create crap like this, but for the most part, it’s an incredible tool.
VueJS: You can get started with VueJS with a simple HTML file without ever touching Webpack, babel, or NodeJS. Simple script tag that’s it. While the same is also possible with React, if you don’t use JSX, it’s incredibly difficult for practically use. As you progress further, you get the idea that the project’s objective is to help developers do more with less. Want a keypress handler? Use
@keypress. Want a keypress handler for the space key? Use
@keypress.space. The design of Vuex store, too, is incredibly simple and it clicks almost immediately.
SvelteJS: Although I haven’t personally used it, I love the simplicity of Svelte’s design and the conciseness of its syntax. The idea immediately clicks as well: if you’re compiling your code (to use babel or JSX), you might as well do it in a way that bundling the library isn’t needed. I also like the fact that Rich Harris, author of the project, challenges the accepted wisdom like Virtual DOM was a step forward.
Astro: Another well-designed project that just works. In Astro, everything (layouts, pages, components) is a variation of Astro Components. This architecture feels simple and clicks immediately. It doesn’t take long to feel productive with the project. I also find the goals of the project’s co-author, Nate Moore, to be much more laudable.
When did front-end go so wrong? I remember when jQuery first came, it was an instant hit. Selecting elements and doing DOM manipulations was a giant PITA. jQuery suddenly made them too simple to ignore. You could have started using the library in production in less than an hour.
Granted, we are dealing with a different beast here (rich, dynamic apps), but that doesn’t mean it necessitates all the layers we have added over the years. Creating declarative UIs shouldn’t be hard.
We have to get our priorities straight! The focus should be on simplicity, conciseness, and approachability. Clean syntax that gets the job done. Not a hundred lines of boilerplate to do a simple thing.