The Business Case for Vanilla JS
32 points by ugur
32 points by ugur
Perhaps frameworks, like React, are a byproduct of their time. When Vanilla JS was not nearly as good or standardized across browsers yet. And then people kept using them after it was no longer necessary because it was the devil they knew. But this is just a guess, as I have never really used JS or React.
Unifying browser APIs and JS features was more a jQuery thing than that of frameworks, and we reached that stage aons ago, counting in webdev time.
Now, if web components are considered done, we might be one step closer to reaching feature parity with early React. Whether that's the case I leave to those who did something with that recently, last time I checked it wasn't worth it for any of my use cases. Never mind the whole shadow root thing…
But let's say that's done and you can now write components in plain JS. Evergreen browser support is ok, no weird Safari glitches. You're okay with the more involved parsing of arguments, just like you were okay with more code after going away from jQuery. Now, how do you manage interaction? Where do you keep your state? How's tool support for writing and checking the HTML in your components? How do you handle basic iteration? This hasn't changed a lot from before the time of frameworks.
The article has this to say about it:
In one you pretend you're writing a sort of pseudo-functional view model, in another you manipulate html.
Technically correct. And I agree that the abstraction leaks at time, as does any abstraction. I'm not so sure whether the problems with the abstraction are even remotely in the same ballpark as those with the raw platform. It feels a bit like people saying that the Win32 event loop is the one true way of doing Windows UI interaction (I guess you'll find those people, probably on YouTube). To me, the signals of Qt or SolidJS/Preact/Angular feel like a nice improvement in usability, and the other people on the team probably know them better than whatever I added on top of plain JS.
Now, I see two major cases where plain JS would be an improvement over frameworks. The first being the rare hyper-specific JS app, done by a very small group or a single developer. Here friction and abstraction leaks are more likely to happen, and performance can be crucial. Photopea probably fares better with being plain JS.
The other case is "old school" JS, i.e. enhancing a page where most of the things are done on the backend (or not at all, if it's just showing text and images). Some optimistic rendering, some niceties for form handling or checking errors that go beyond what HTML5 can offer. Something that you can also live without. You probably won't run into big problems with keeping state or re-rendering parts of the UI here.
Granted, I'd probably have a look at HTMX or Unpoly there, to get even less JS into the picture, but if it can be done with 50 LOC like OP's issue, it's better than dragging in React or something even bigger.
But here we're going into the frontend-backend split, which is causing turmoil even within the framework spaces, where "server side rendering" is often considered a hot new thing (by now, a lot of developers in that area never touched a backend-language template engine like Jinja or Struts). Nobody cares for progressive enhancement here, but hype and performance fight against one of the major reason for the popularity of JS frontends & frameworks: Conway's Law. The frontend being yet another microservice and thus team seems a major benefit for a lot of organisations, and decades of that also had a major influence on developer skillsets.
Does plain JS work with that as well? Does vibecoding really change it, given that a lot of the training data is framework-based?
I agree, IMO React is a product of the time before AI made churning out idiomatic and fast JS/HTML more trivial than cajoling React into the right thing. At least there were years where accepting its viewpoint saved you a lot of typing.
As it is, I can't stop AI-written React from eventually entering a render loop or being janky since it's unaware of React's unique restrictions / "imposements", which for some reason are still not compile-time or even run-time errors. Just steadily more jank until you bring in some "architectural solution" (which to front-end devs often means yet another library involved in slowing down your front-end UX and DevEx, esp. when oh god one lib updated and doesn't work with the another crucial lib anymore, or shadcn's table component is actually totally unusable for real non-toy tables...more more more! More crap to patch over the holes in the old bloated crap!)
Vanilla JS was not nearly as good or standardized across browsers
Your point reminds me of a recent article about front-end developers, trust, browsers, and third party libraries.
I would say the biggest benefit of React style frameworks is that they're declarative by nature. He addresses that and points out that React doesn't really achieve that cleanly, but React is a first generation declarative web framework and I think it has reached the limits of what its architecture can achieve. He doesn't address newer declarative frameworks which do a much better job at achieving the declarative promise, particularly with signals.
I agree that, in the meantime, js has matured much since frameworks like React were introduced and now coding agents are much better at writing vanilla js by itself.
Still, recently I also did some experiments with having llms write vanilla js instead of using a framework. It looks like they still incur in the same synchronization problems of writing code by hand had so I think declarative frameworks will still be able to help, also for managing reactive state in a more centralized way.
That said I'm pretty sure we can potentially have the cake and eat it too if we can give precise enough guidelines for how structuring a large vanilla js application (i.e. how to correctly compose mounting and unmounting logic using combine, using signals as a reactive primitive, don't use create elements imperatively but use a very small handler for readability, use specialized diffing chirurgically when working with lists of components, oh and css is also good now with nesting, layers and :has selectors, ...)
P.S. I have many ideas about this xD, I think I will write a blog post sometime soon
I'm all for reducing the amount of fronted library "noise", but I've always felt that the value of React was to compartmentalize logic and to scope code to the HTML/CSS it's closest to.
Without it, with vanillaJS, most things are just bound to the "global" scope (document, window), right? That's fine for smaller apps, but it gets unwieldy as your app grows.
I'm interested in seeing if a lighter-weight approach comes up that solves this without the complexity of React.
Web components with attached stylesheets do solve most of what you've mentioned, though I'd say the DX story is a bit clunky. You're still getting access to the shadow DOM (if you want to use it, though light DOM is also easily manipulated) and a "this" scope for the component. Each component is nicely encapsulated and easy to reason with.
I recently migrated away from using inline scripts for a lot of things to using custom web components to make it easier to compartmentalize, and it works pretty well.
This idea has been posted a few times lately. Most recently, yesterday: https://lobste.rs/s/qywh3s/with_ai_you_barely_need_frontend
Have you tried to write framework-less JS for a large app? Web Components only support strings for message passing. Have fun JSON-round tripping all your complex data types.
Angular does a lot for me.
I think the selling feature of a framework like React is that it can target more than the DOM. There is react-dom which we mostly use for building SPAs, but there is also react-native, react-email, react-pdf etc which target different view layers. I'm not a particular fan of the framework but I think the real sell here is its defined patterns working across different platforms for building frontend UIs.
How true this is in practice - being able to use my react-dom components across in react-native or react-pdf - is not something I have actual experience in. I typically agree with the author though that if you want to add a bit of interactivity and dynamic content to a web page, just use some vanilla javascript.