The Business Case for Vanilla JS
I am no longer a proper front end web dev. And I love it.
During COVID I was. I bundled, I transpiled. I reacted, and I source mapped. I knew the rules of hooks, and was wise in the lore of tree renders. Now, I can't be bothered with any of that. If I need to write a web app in 2025, I am using Vanilla JS and browser APIs directly.
Here I will argue this is the pragmatic choice for anything that will be in production for more than a few months. The maintenance story is much better; browser APIs continue to improve, remain largely backwards compatible, and are a less risky proposition than going all in on a single, rapidly moving JS framework. Vanilla JS itself is excellently documented; great not only for your own sanity, but for any LLMs you ask to generate code. And the developer experience is a breath of fresh air! Gone are source maps and transpilers; you are free to simply script the web page directly, as was intended.
I came to this way of thinking by sheer accident. I was traditionally a desktop business app developer, and by the time I saw the writing on the wall, SPA frameworks were the dominant meta in front end. As I started getting contracts, I worked on one project with such a tight deadline that I simply had no time to bring a critical library into the cinematic React universe. So I just... wrote JS. I modified the DOM. And you know what? It was fine. Not only was it fine, it was easier. I wrote a little stream object in ~50 LoC to react to user inputs, and it worked flawlessly. I felt lied to. I thought making a web page interactive was an insanely difficult task only SPA framework authors were qualified to do? Yet here I was just... scripting the page.
Fast forward to this month, where I needed to present an HTML report as part of a Deterministic Simulation Testing project. At this point I'd had a long break from frontend, and my skills were rusty. My first instinct was to follow so-called "best practices", and I used Preact. But as I went on I saw errors relating to "Hydration" and "Component Trees" and I realised not only had I forgotten what these things meant, I also no longer cared. I thought back to my old vanilla JS project, and once again I just started using the platform. And once again... it was fine. It was better.
The myth of React
But surely I'm being unprofessional. Surely one should use react, or another modern framework1. Surely raw javascript is re-inventing the wheel!
(As an aside "raw javascript" - and its cousin "raw CSS" - strikes me as a silly term. I'm not toggling switches to enter hex code on the front panel of a mini computer, I'm using a garbage collected scripting language with closures and prototype chains to manipulate an interactive document. But I digress)
To which I say: I don't see it. React is talked about and marketed as an abstraction on top of the DOM. This may be technically true, but it is not the truth in spirit. React.js does not operate at an appreciably higher level of abstraction than the underlying browser APIs, rather it presents an alternate abstraction. A popular abstraction to be sure, one that comes with its own debuggers, compilers, linters etc. But at the end of the day it's just a different way of looking at the same problem. In one you pretend you're writing a sort of pseudo-functional view model, in another you manipulate html.
And as a functional and "higher level" abstraction, React.js falls short for one very simple reason; the abstraction leaks like a sieve. It's "declarative" right up until you're debugging stateful hooks, or resorting to useRef
, or trying to reason about when a "component" re-renders. It's for this reason I don't consider react particularly well suited to larger, more complex web apps - in my experience things rapidly spiral out of control and relatively few people in frontend - a field that trends very junior - are able to make sense of the resulting problems. Of course, this happens with any technology, but if so - why bother with the slower, less stable, and less fundamental abstraction? Just use the platform. It's got problems too, but it'll always be around.
Footnotes
-
I am perhaps being unfair to other frameworks, of which I have limited experience in. If their story here is substantially different, I'd welcome feedback. ↩