Rendered at 23:01:45 GMT+0000 (Coordinated Universal Time) with Cloudflare Workers.
onion2k 2 days ago [-]
So many more problems solved…
Those problems aren't 'solved'. The author has an implementation of a solution. It's one that they think is good, which is ace and I'm happy for him, but if he ever introduces a second developer to his project those 'solved' problems will become a point of friction. They'll go from 'solved' to 'solved, but in the wrong way' or 'solved, but not for this edge case', or 'solved, but why is the code so verbose?'
The massive advantage of a framework is that the people who choose it have agreed to share a solution to the common problems. This cannot be overstated - as soon as your team grows to more than one developer you move from 'solve the problem' to 'solve the problem in a way that people agree on', and that is far more complicated than just solving a problem. Sometimes you get lucky and work with people who think the same way as you, or with people who are willing to compromise on their ideal solution and accept yours, and then things still work, but if they're 'passionate' about being right then it's horrible, slow, and results in bad code.
A framework is an upfront agreement about how to build something. That has no practical advantage for a dev working alone. It's incredibly useful for two or more devs working together. Which framework doesn't really matter, except the ones with more devs behind them make it a lot easier to find people who've already accepted that way of working. That's helpful.
Kon5ole 2 days ago [-]
>if he ever introduces a second developer to his project those 'solved' problems will become a point of friction. They'll go from 'solved' to 'solved, but in the wrong way' or 'solved, but not for this edge case', or 'solved, but why is the code so verbose?'
I agree with the problems you list, but I don't think a framework solves them. The same complaints can be made by the second developer because the first developer chose the "wrong" framework. Solved the wrong way, not covering the edge cases of your domain, too verbose etc.
Additionally a framework will likely be bloated and inefficient because they try to solve every problem for everyone, and you introduce a random breaking point where any framework update could in theory break your system.
Rohansi 1 days ago [-]
> The same complaints can be made by the second developer because the first developer chose the "wrong" framework.
Exactly this. There's so much fragmentation within the browser ecosystem that there is no guarantee your second developer will be comfortable/familiar with what the first developer chose. Even if you went with React you could be using state management they don't understand, a styling system they don't understand, etc... Even if you choose the most popular everything at the start of the project there is a lot of churn where things eventually fall out of favour.
I'd also be skeptical of web developers who work with React but aren't familiar with vanilla JavaScript. It's probably a good indicator that they aren't the best candidate but we can't all be picky.
winrid 2 days ago [-]
you just agree on a set of conventions for components and state management, it's not that hard. This is basically how Rails works...
yes it's still a framework, duh. it's just less abstraction than react etc.
onion2k 2 days ago [-]
Sure, and if you like working with the conventions and abstraction Rails offers that's great.
Other people make different choices. That doesn't mean they're wrong.
winrid 2 days ago [-]
To write good React you have to follow conventions, too. You can't get away from conventions.
People keep touting react etc but I swear every mobile ordering app I use lags like hell, just from recent example, and these can easily be built and maintained without a huge framework to "manage state" or "connect state to the view".
onion2k 2 days ago [-]
People keep touting react etc but I swear every mobile ordering app I use lags like hell..
I don't doubt it. People make terrible websites with React.
However ... what might be happening is that you go to some websites, and some of them are great and others are terrible laggy garbage. When it's a bad one you open up devtools and see React, and that leads you to conclude that React is bad. But reality is that the good ones also use React, because most big websites use it.
Your reaction to the good ones is to assume they're well-built using whatever tech you happen to think is great (Rails, Vanilla JS, Vue, Svelte... whatever) but you're not actually looking. Hell, a great website isn't even a website, it's the experience of interacting with the business behind it. You don't even think about the tech when the website is actually usable.
Your reaction to the bad websites is to look under the hood, and you often find React.
That either means React websites are bad, or that React websites are good or bad, and it's not really React that's the issue. It's the team who built the site (and often not even the tech team; there's often some Product or commercial pressure that's driving the team to release something that's not really ready yet.)
winrid 2 days ago [-]
I'm not sure I'd say "React Bad", I'd rather say "React Not Really Super Necessary and More Often Than Not Leads to a Worst Experience at Maybe a Slightly Lower Initial Cost" :)
I did an experiment recently, I actually wanted to launch a dashboard and picked React because I knew I could throw React + Tailwind + popular_component_and_charts_frameworks at Opus and get a decent result. But actually, I realized a lot of fairly simple button clicks had like a 100ms-200ms delay, and I just did not like it. I ported it to Java/Javalin with J2HTML and kept tailwind, and it's very snappy and works great. It's currently 96k lines of java ^_^
torginus 2 days ago [-]
I've had someone tell me to not bother with list virtualization under React, since the 'computer's fast, it won't matter'.
We shipped it like that. Turns out the computer's not fast and it does matter.
dcow 2 days ago [-]
So React is like C++?
pkphilip 2 days ago [-]
Absolutely agree. I hate the state management mess in these frameworks.
bellowsgulch 2 days ago [-]
A lot of web development problems are solved. That's what this author and many other very experienced jaded principal engineers try to say year after year.
Because you think whatever you want to pretend your web software isn't MVC isn't solved doesn't mean it's true. Oh brother, MVVM, Model-template-view (no offense, Simon), come on.
You define resources on an HTML page, the browser loads them, renders a page, loads scripts, and makes AJAX calls.
You don't need build scripts for this. More over, these frameworks and build scripts DON'T SOLVE PROBLEMS. They move them. They want you to become a React developer. Not a software engineer who writes web software.
They don't solve routing, because you rewrite it every year. They don't solve bundling, because you change bundlers every year. They don't solve event handling, because they just move the chain of calls where you define the listener.
It's all a lie.
root_axis 2 days ago [-]
Labeling UI frameworks as artificial complexity is simply a sign of inexperience manifested as NIH syndrome.
The vanilla approach is fine for a personal or toy project, but it's an unmitigated disaster for a project with even a moderately complex UI.
Eventually, the vanilla project becomes its own bespoke UI framework with a bunch of poor design choices because all the complexity that was dismissed as "artificial" eventually gets patched in using a rube-goldberg-machine approach to architecture.
umvi 2 days ago [-]
Not everyone is building complex UIs like google sheets. Most people are building static pages with a sprinkle of interactivity, or maybe form pages for doing CRUD.
ganzsz 2 days ago [-]
It starts as simple crud, but then product introduces a business rule where some fields need to be hidden when another option is selected somewhere. O, but not when this checked, etc. Having a reactive framework when this happens is very much needed to keep all these effects working without a lot of vanilla JS.
This can be solved later, but is a lot harder when you have an entire application that needs to bee kept working, and almost trivial if you started with some reactivity built in.
evolve-maz 2 days ago [-]
A lot of rules like "some fields are hidden / shown based on other fields" come from restricting users to only expressing valid object states. E.g. I have a form where a user can pick a "notifier". They get a first dropdown select which is email or teams-message. Then based on that selection to get another which fills the details relative to that.
In that case, the backend will likely have a class instancr representing it, with the first field being a discriminator on the class and the remaining fields being the details. And regardless of what the frontend does, the backend will revalidate always because you can never trust data sent from a frontend.
All that to say, maybe the form could be server side rendered, with an adaptor to convert a class definition into an html form fragment, and either embedding the js "rules" into the html itself, or making it a web component for containered usage.
Doing it this way is a big deviation from the current status quo, but I've found it to work very well and cut out a whole range of bugs. Plus it makes me think about what is truly client side state (no chance of staleness) vs server state cached in client to avoid repeat server calls (could be stale, leads to bugs).
inigyou 2 days ago [-]
Your first thought might be to use React, but in prior eras we wrote a function updateFieldVisibility() and that worked fine. Straightforward code can be faster than using a state management framework to determine exactly which fields' visibility changed.
dsego 2 days ago [-]
But it's harder to have component composition. Consider also lists and adding/removing items and so on, juggling all of it gets insanely complex and requires MVC or MVVM patterns like with backbone.js
oneeyedpigeon 2 days ago [-]
But now we're back at "Not everyone is building complex UIs like google sheets". I agree with the underlying sentiment of this thread: overengineering is way more common than underengineering.
dsego 2 days ago [-]
Eventually each crud form evolves into something more complex, the bar is set higher today, we expect pagination, filtering, search, inline editing, grids, instant validation, auto-save, push notifications, state sync, ... that's not a complex UI nowadays, it's expected. Not sure what a non-complex UI looks like.
inigyou 1 days ago [-]
You just call updateFieldVisibility() every time the list selection changes and don't worry about the redundancy.
not-a-llm 2 days ago [-]
it can be faster, but is it correct?
React was invented because jQuery style state management collapsed into unmanageable code past a certain size
dsego 2 days ago [-]
And it wasn't composable, state was kept in the DOM. Even with higher level libs like backbone we didn't have a component-oriented way like now. Each component had to manually manage all of its child components.
inigyou 1 days ago [-]
It composes to one level. Each <input> is a component. Is that good enough for your application? For many, it is.
dsego 13 hours ago [-]
Really sorry to have to say this, but I feel like I'm getting underpaid for the work that I do if people make a living clobbering together input elements and calling it web development.
wasmperson 23 hours ago [-]
> but then product introduces a business rule where some fields need to be hidden when another option is selected somewhere
function initWidget(root){
// Or a bunch of calls to document.createElement, whatever you want.
const inp = root.querySelector('.input');
const check = root.querySelector('.check');
function update(){
inp.style.display = check.checked ? 'none' : 'block';
}
check.onchange = update;
}
> O, but not when this checked, etc.
function initWidget(root){
// Or a bunch of calls to document.createElement, whatever you want.
const inp = root.querySelector('.input');
const check = root.querySelector('.check');
const check2 = root.querySelector('.check2');
function update(){
inp.style.display = check.checked && !check2.checked ? 'none' : 'block';
}
check.onchange = update;
check2.onchange = update;
}
IME almost none of the complexity in any of the web applications I've worked with has been mitigated by the front-end framework in use. You still need to write the code to do the thing, whatever that thing is. You might as well write it in the framework that gives you the smallest bundle size and the best possible backwards compatibility, and that's vanilla JS + the standard web APIs.
shunia_huang 21 hours ago [-]
I'm not reading the code on HN but I do second this. After implementing a enterprise level production app by myself months ago with vanilla typescript, I find it's much easier to think the vanilla way than adapting to React or things similar. Before this project I work with React for years and never looked the other way. The reason I chose vanilla typescript over React is for performance as the app requires tons of resources and I want to keep it minimal without the performance punishment, but ended with a much better experience for UI development.
You don't need to remember how to properly line up useState/useEffect/useCallback and all.
You could just insert any simple state object and be ok with it, or insert a well-known state management library and it still works the same way.
For UI libraries they almost always have a vanilla option, and even better, if you are not working with google sheet level of stuff, vanilla element management is much much easier to work with.
And no need to talk about the style frameworks, they always work the vanilla way.
With some default vite configuration, nothing you need to worry anymore and the framework level stuff are simple and easy to understand and is totally manageable.
root_axis 2 days ago [-]
As I said, any app with at least a "moderately complex UI". If your app is just a sequence of web forms and stays that way forever, then you're not the target audience of a UI framework anyway.
lenkite 2 days ago [-]
Regarding puzzling design choices, I am wondering at the preponderance of data attributes like
For custom web components, maybe the author forgot that you don't need to prefix attributes with data ?
megous 2 days ago [-]
You don't need it anywhere, unless you want to use dataset property.
twhitmore 2 days ago [-]
Or not. For simple to moderate requirements, plain HTML with a small templating helper is genuinely simpler than React.
React’s complexity isn’t just components — it’s effects, state‑management conventions, data‑loading patterns, and the surrounding build ecosystem. If your UI doesn’t need those abstractions, adopting them early is pure overhead.
For these kinds of projects, React usually carries a much larger total cost than vanilla HTML + JS.
The “vanilla becomes a bespoke framework” claim assumes the UI will inevitably grow until it needs framework‑level abstractions. Most UIs don’t. React front‑loads complexity even when the UI is small, while vanilla only adds what the actual requirements demand.
A few helpers aren’t “reinventing React” — they’re choosing a simpler design avoiding numerous unnecessary abstractions, and with lower costs & complexity for the moderate apps they're building. It's a very valid architectural choice.
dizhn 2 days ago [-]
[flagged]
WhyNotHugo 2 days ago [-]
I appreciate the sentiment, but can't agree fully. I used vanilla JS for many years before AngularJS even existed (and I also tried AngulasJS when it was the new thing).
Vue is just a huge convenience over raw JavaScript for large, complex view. Sure, I don't get to do direct DOM manipulation, but when I write C code I also don't get to pick which variable goes in which CPU register. I accept giving up control that ASM would give me, for all the improvements that C brings on top of it, even if C just compiles to ASM and is an abstraction on top of it.
stana 2 days ago [-]
Writing programs in C has simplified developer experience over Assembly. Issue with JS frameworks is that many find them complex, i.e. complexity has not been abstracted away (which should be goal of abstractions). Maybe DOM manipulation has, but many new complex ideas had to be introduced to achieve it.
dsego 2 days ago [-]
But isn't that the right thing to do? Recognize the problems and introduce concepts to tackle them. C introduced pointers as a concept, one more thing to learn and reason about but frees you from using addresses directly. Relational models was discovered as a formal way of understanding and reasoning about data structures. Frontend components introduce a composable architecture with lifecycle hooks, reactivity etc. Those concepts were already there (e.g. with ad-hoc html templates, event listeners, clean up code) but now they are actually formalized and made explicit and developers actively think about them when doing frontend. So the abstraction is there, but I feel for some reason non-UI people assume UI is easy to code, but they never thought about the actual concepts involved. Even without frameworks, you need to consider composability, modularity, events, life cycle, state management, async behavior, etc. I'd rather have those built in and considered as part of the programming model, than to avoid it.
JBits 2 days ago [-]
Is it mainly the reactivity part of Vue that you benefit from, or are there other aspects which are important?
nilirl 2 days ago [-]
> The idea of reactivity came from or was popularized by Angular.js
No, spreadsheets popularized reactivity. And the general point is incredibly weak.
Don't use frameworks and make your own? Sure, have your fun. But then try teaching your framework to your company of 1000 and see how quickly you realize your view of the "problems" are only a slice of the pie.
rablackburn 2 days ago [-]
How many companies have 1000 frontend developers?
Do they need 1000 frontend developers?
Aside from the Giants maybe some consultancies or hire-firms have that many? But they use whatever the client uses. If you're not in the business of selling frontend development services then a big part of your competitive advantage is _being able_ to make technology choices that are more-optimal than the labor market's lowest-common-denominator slurry.
Between JS/ECMAscript being abandonware for a decade and CSS' historical immaturity (cross-browser layout, custom properties, more pseudoclasses, etc) the Web was more of a wild west "whatever you we can cobble together" place. So of course we built an entire toolchain ecosystem for all the cool new tools we would reinvent from scratch.
but Things Are Pretty Good these days. We even have the world's only fully system portable assembly language: WASM! And the browser's Web APIs are becoming something like the missing Standard Library (shoutout to Deno).
The author's point seems to be that we are past a tipping point where we need all that additional complexity. You don't _need_ a separate system of reactivity these days, you can write a (closer to pre-hooks React, even!) React-style component library with Web Components now.
Personally I would need for Type Annotations to be a fully supported part of the spec before I made the point to "use the platform" professionally. Until some market force causes the core web technologies to truly fork my skills are useful for life. It's like a pale shadow of how UNIX users must feel :')
nilirl 2 days ago [-]
My point was your needs and problems are not everyone's needs and problems.
I don't want to think of memory management in most projects, I want to focus on business logic, so I use Node.js instead of Rust, even if the latter gives me more control.
Similarly, I don't want to think of DOM management in most projects, I want to focus on data dependencies, so I use React instead of Web Components, even if the latter gives me more control.
doginasuit 2 days ago [-]
This hit so close to home. For the last eight months I've been building a web app without any major framework like react or angular. Angular taught me a lot of important lessons about best practices for structuring UI. But eventually you run into boilerplate that doesn't jive with what you want to do.
The author frames this as artificial complexity, and that's the best framing I've seen. The browser has a particular presentation philosophy and the more you try to cover it up, the more awkward your code becomes at the edges.
The killer application of LLMs is their ability to inform and adapt to a particular API, and analyze the code that you write. They are garbage at producing functionality for which they don't have a thousand examples, but provide documentation and intent and they will help you fill in the gaps. This is the real 10x opportunity, and the best part is that you can still write all the code yourself.
I'm certain this doesn't just apply to javascript and the web. I predict that the need for frameworks will slowly go away.
mrugge 2 days ago [-]
LLMs are non-deterministic and can benefit from guardrails which frameworks happily provide.
doginasuit 2 days ago [-]
If you are relying on a LLM to write the code, sure. But no amount of guardrails can maintain the quality of a primarily LLM generated codebase.
rerdavies 2 days ago [-]
Claude 4.6+ seem to work fine with my React/typescript apps.
JodieBenitez 2 days ago [-]
> Multi-page applications are slow to load and navigate.
A bit tired to see this...
No it's not. We do this all the time. It's as simple as using proper HTTP headers for your css/js/pictures/whatever. You can even have smooth page transitions now.
simondotau 2 days ago [-]
A browser can load a singular page within tens of milliseconds of receiving the packets. It literally cannot get faster. Single page applications only feel faster because there's no risk of white flashes.
Multi-page applications are slow if you load in 20 libraries from 10 different CDNs, a page tracking system, a click tracking system, a "performance metrics" system, a chat bot overlay, an advertising platform, all the crap loaded by the ad intermediate, all the crap loaded by the ad itself, an ad "traffic quality" montor, a Stripe.com thing (even though this isn't a payment page), something from Facebook, something else from fbcdn...
1 days ago [-]
interf4ce 1 days ago [-]
100%
The author is reinforcing the false dichotomy between using front end frameworks and hand-rolled JS, as if rendering data from JSON APIs is the only way to display information from the server.
Almost as an aside, he says
> Server Side Rendering is also no better, because while they can do certain things in more straightforward way, they break browser behaviour [...]
but he provides no examples or supporting evidence, so it's difficult to know what browser behaviour he's referencing. "SSR" is just how the web has worked since the beginning and it works very well. Maybe he's specifically talking about SSR as provided by Next? I've never used it, so I'm not sure what browser behaviour it might be breaking.
dominicrose 2 days ago [-]
HTTP was designed for multi-page applications/websites but I think it makes sense that Facebook migrated from basic PHP/MySQL to something more complex including React and making less full-page navigation events, for performance reasons (server costs and mobile loading time). There's also UX because a PHP website can feel a bit static, with less animations.
But yes the web has evolved since then and the HTTP protocol has newer versions and most apps don't serve as many users as Facebook.
adamtaylor_13 2 days ago [-]
Did I misunderstand or was that whole rant just to establish that, actually, we do need super tiny frameworks for the front end, but they're super tiny so it's not a big deal and they're not bad like React?
Lerc 2 days ago [-]
We don't need things taking control from us. Or dictating the terms for manipulating an already defined interface.
If that means you have to make a small thing that is designed to do just the task at hand but to do it well, I am all for it.
I think the only frameworks that I have encountered that I felt were worth using were server side things like express where they had a very specific task to do and could isolate areas of behaviour.
dsego 13 hours ago [-]
It's not terms, it's structure. You all seem to be fighting calculus and saying knowing addition and multiplication is enough. I'm reminded of friends refusing to learn chords on guitar and trying to invent their own musicality so they are not constrained by music theory.
Lerc 10 hours ago [-]
You don't get situations where you can say that group theory would solve this bit really well and this bit could have been done with addition and shifts, but we have already committed to using calculus so unfortunately we can't use it,
hoppp 2 days ago [-]
Did anyone else notice the pattern that ever since the LLMs got popular the "I hate javascript" kind of posts or comments have decreased?
It could be attributed also to typescript dominance of course, since people don't use plain js anymore.
As for the blog post, I agree, I also implemented my own js framework when I code in vanilla js and it works fine.
The problem is not inventing frameworks, the problem is that everyone invents frameworks, so people all know different things and they are hard to hire.
foobarbecue 2 days ago [-]
I think the complaints attenuated in the last in the last 10-15 years because javascript itself became a much better language. Things really started to change with ES5. The introduction of let / const, modules, async, .?, template strings, etc. transformed it from an ugly kludge to a really capable language.
Of course, if you use old syntax you still deal with weird scoping and casting, but you don't have to any more.
Also, I think the framework churn has slowed considerably in the last 5 years.
dsego 12 hours ago [-]
Everybody sort of settled on React and Node, or at least on the reactive/declarative component paradigm. React was introduced over 10 years ago now, it's a dinosaur.
motoxpro 2 days ago [-]
My take is that the take that vanilla js is better because developers love coding more than they love building the thing. See all the frameworks/packages built as an example.
This person re-invented form handlers, frameworks, ui helpers just to be able to do some basic things.
All power to you if you like it, its just funny.
prokopton 2 days ago [-]
It’s been a minute since someone ranted about frontend frameworks. Take a shot.
2 days ago [-]
lezojeda 2 days ago [-]
And he ended up... creating frameworks himself. I fail to see the whole point of the article tbh. It's a rant against JS frameworks/libraries and the frontend in general all to end up admitting he did the same?
prokopton 2 days ago [-]
I checked out before getting to that. He even wrote his own HTML variant called EHTML.
Well played. You got me to visit your version of the thing you complained about. :clapping-emoji:
megous 2 days ago [-]
It's not a html variant. It's just a bunch of web components. Takes like 30s of looking at actual source code to figure that out.
dsego 12 hours ago [-]
So like Lit components or Stencil?
hexasquid 2 days ago [-]
> NO, YOU CANNOT JUST USE GLOBAL STATE. USE THIRD-PARTY LIBRARY WITH FANCY FUNCTIONAL DESIGN.
window.i = 0; // initialize all my for loops in one go!
benoau 2 days ago [-]
Some good history of the JS ecosystem here but the underlying message is all the same, frameworks scale and provide structure but you don't need them. Very easy to agree up to this point.
Author then elaborates in the absence of using a common-knowledge framework you can create some tighter solution that achieves just the part you need. This is "fun" programming, and the author is suitably impressed with themselves for solving problems they created just by convincing themself not to use a framework. Sometimes that's fine, although I don't think there's much appetite for this anymore.
Article doesn't really elaborate on what "scaling" and "providing structure" means, I think it downplays the benefits because when you use <framework> you are really establishing ground rules for how all future developers are going to work on that software. You don't know exactly what they'll write, but you know they'll always gravitate towards the top 2 or 3 solutions for that framework at any given time.
When you bust out a bespoke solution that carves out that one thing you needed and does it oh so elegantly and perfectly, you're creating art but most of the canvas is left blank for future developers and they're effectively going to scribble on it with crayons.
bluegatty 2 days ago [-]
You can say that without being demeaning. These are random people acting in good faith.
Also - sometimes it is actually useful to make a mini-thing instead of bringing in enterprise messes.
chabska 2 days ago [-]
These people are perfectly fine with depicting React developers as corporate zombies that can't think for themselves. Good faith is bidirectional.
bluegatty 1 days ago [-]
We can try to be a big magnanimous and rise above a tiny bit of 'English on the ball', let the small stuff slide.
swatcoder 2 days ago [-]
We practice engineering. As engineers, we need to understand the realities of each project we take on. Those realities are not limited to the marketing bullet points we might apply to the imagined product someday, which is what early career folk might naively call "the requirements".
Among the most critical realities to consider exist outside the product definition entirely, and have to do with the environment in which it will exist during and after development. These are things like plausible scaling curves and limits, code lifetime, team size, deployment options and preferences, etc. Others are things like available runway, team fluency and talent, available tools and licenses, etc.
One of the big eyeroll moments of the last 15 years or so was when folks started blindly cargo culting global-scale 10,000-engineer enterprise practices on projects that would obviously only ever be touched by 1-2 technicians and deployed on a far far far more modest scale. Instead of actively considering any of those environmental requirements above, "engineers" would try to treat every project as though it would someday service 10,000,000 DAU under the hand of dozens or hundreds of churning technicians.
Akin to the joke about some Americans who see themselves as "temporarily embarassed millionares", making foolish choices at their own obvious expense, many engineers during this era would seem to see themselves as "temporarily embarassed Facebooks".
In countless cases, this was simply very dumb and very wasteful and at best amounted to inadvertent (or perhaps intentional) resume-padding for the people involved, while their projects bloated and sagged and lurched under unwarranted complexity.
Sometimes (in fact: often), just doing the thing well with simple, clear, stable tools -- and nothing more -- is the right choice.
RetroTechie 1 days ago [-]
> Sometimes (in fact: often), just doing the thing well with simple, clear, stable tools -- and nothing more -- is the right choice.
Stronger: that should be standard operating procedure. Unless there's a pressing need (if not absolute necessity) to do otherwise.
shimman 2 days ago [-]
It is truly insane that this still continues to happen today, I mean the entire cloud industry is built on overcharging clients for compute they will never ever realistically use.
Not too mention how damaging it all is to environment in exacerbating the climate catastrophe.
FpUser 2 days ago [-]
>"frameworks scale and provide structure"
Web Components and vanilla JS scale just as well. Been doing this for ages.
wett 2 days ago [-]
Asking in good faith: how is your experience working with vanilla JS on a team?
While I’m not the biggest fan of Nextjs for my own solo projects, I really enjoy using it at work. Leaning into the opinionation it provides/encourages keeps my team from bickering too much about how to structure things.
It’s really nice to say “this is the idiomatic way of doing it according to the docs” and for everyone to nod their head. Whereas pages in our legacy PHP codebase look completely different depending on who implemented them.
pjmlp 1 days ago [-]
You impose static analysers on the CI/CD pipeline, or git pre-commit hooks for code style?
Folks learn about how to use modules and libraries?
FpUser 1 days ago [-]
Team or not makes no difference.
Front ends works like this - main app split into few smaller ones callable from a menu. Each sub-app is dynamically imported module (no need for building, code mutilation, direct dependency etc). Sub-apps in turn can consist from the other sub apps. Each can be worked on completely independently by different team member with virtually no interaction needed. Apps can share some approved libraries (like for graphics etc) and HTML components responsible for particular bits and pieces. Components and libs go into common pool. Once component is in a pool modifying behavior is punishable by death. Only internals. If change is breaking then simply new version is developed and deployed.
The whole thing is super scalable organization wise (nearly everything is decoupled) and resource wise as well since everything is loaded strictly on on need basis.
pikeangler 2 days ago [-]
I use Svelte 5 (without SvelteKit) for my SPA's, after doing my first SPA in vanilla JS. Then I discovered Svelte. Svelte is very close to the platform and still solves a lot of problems: for reactivity, modularity and CSS cascading (and in version 5 it is not too "magical"). A lot of the critique of frameworks in this article does not apply to Svelte.
dsego 13 hours ago [-]
Svelte needs a build step, and with the introduction of runes for reactive state it's not that different from the rest of the crop (solid, react, vue).
andrew-dc 1 days ago [-]
My experience with Svelte has been similar. Svelte struck the right DX balance for me between helpful framework tools and features, but not far removed from vanilla JS, HTML, and CSS.
And sure, there is a build step. I have never felt like this was a problem with Svelte, but then I don't have experience working on a colossal Svelte app. Does it become one?
ciconia 2 days ago [-]
How so? Svelte provides a bunch of (very nice, no doubt) abstractions for building web UIs, and there's a build step. In that regard, Svelte is no different from other JS frameworks.
rimliu 2 days ago [-]
The hint how Svelte is different is in the word "different".
tancop 2 days ago [-]
[dead]
sheept 2 days ago [-]
Vanilla JavaScript makes sense for personal projects, but if you're working on a team, I wouldn't trust other team members to not create their own frameworks that may not be as well documented.
Especially nowadays with LLMs, the team would benefit more from the LLM innately knowing a widely used library/framework than having to spend context each session teaching the agent your custom setup through context files and skills.
austin-cheney 2 days ago [-]
Sure, when I wrote JavaScript for a living I wouldn't trust my employer to get hiring or training right either.
socketcluster 2 days ago [-]
I love vanilla JavaScript. All my personal projects are plain JavaScript. No Typescript. But in a company setting, it's almost impossible to find plain JavaScript roles.
Plain JS is also a lot better with AI. I don't recall Claude ever making any mistakes in terms of getting the type wrong with plain JS since I started using it. It's just not the kind of mistake that AI makes.
I feel somewhat vindicated by this. I've been saying for years that coding isn't the hard part, type correctness isn't the hard part. I also made a point that complex interfaces are a greater danger and that Typescript tends to encourage people to design complex interfaces... And look, this certainly seems to be reflected in the training data because my AI token usage at work (Typescript) is far greater than on my side projects for the same task complexity.
This is kind of proving my point that plain JS code is better architeted overall than Typescript code... It makes sense to me, any complex plain JS code MUST be well architecture because JS is unforgiving. The spaghetti doesn't go very far in JS.
bigcityslider 2 days ago [-]
Same, but the article isn't about JS vs TS, it's a criticism of frameworks.
didip 2 days ago [-]
If we are going to rant like this… i’d say even most of JS is unnecessary.
Just use server side template rendering with HTMX. LLM can see server side request flow better anyway.
ChadNauseam 2 days ago [-]
As a user I don't really appreciate sites that do this as they tend to have worse latency for UI interactions and less pleasant page transitions. And of course, they are unusable offline
bfjvibybd6cuvu6 2 days ago [-]
My sites with htmx have less latency for ui interactions and page transitions work like every page on the internet.
As for offline, yeah, my Internet web page doesn't work offline. Shocker.
ChadNauseam 2 days ago [-]
> As for offline, yeah, my Internet web page doesn't work offline.
That's really too bad honestly. What about your users who want to use your site when they're offline? Sympathy with those users is why I made sure that my site works well when offline.
interf4ce 1 days ago [-]
Whether this is actually beneficial (let alone possible) depends heavily on the type of site.
Web apps that are valuable to use offline also tend to be the kind that really do warrant client-side logic and rendering (a spreadsheet web app is a classic example).
If the site's focus is providing information (e.g. Wikipedia), then working offline really just means loading all the backing data into the browser, which quickly becomes impossible.
I'm sure there are cases where offline availability is a huge plus (your site might be a good example), I just don't think it's universally applicable.
vsgherzi 1 days ago [-]
I can offer a slightly alternate prospective. At my current company we’re a small team that needs the frontend to stay stable with little changes for long periods of time. Our major react site has rotted due to us not keeping up with the Churn of the ecosystem. We don’t have a complex ui. We just need stability. Keeping up and managing a framework has been too much when we don’t have a dedicated frontend team.
olavgg 2 days ago [-]
I fully agree with the author, and I have stayed on vanilla JS for decades now. I like the simplicity, ownership, zero dependecies. I have my own bundler in Spring Boot using Google Closure Compiler, which works autonomously with the javascript assets. No nodejs needed.
Also with the developer disruption of agentic coding AI, the arguments for using vanilla JS is even stronger. Code reviews of code/solutions is much easier. Scoping of code paths for each server-side render templates is easier. The AI does all the boilerplate coding, while keeping it readable and debugable. Implementing design patterns is just common computer science stuff, and the coding agent is pretty good at it.
I also what to mention, as a business owner, and boss of a startup. All developers here work with vanilla javascript. They were first surprised, but today they prefer it by a huge margin because of the simplicity and zero dependency and non existing build steps. The web browser is the framework, you need another abstraction over the web browser.
danielvaughn 2 days ago [-]
I've been considering going back to vanilla javascript, given the current power of LLMs. It could become unreadable spaghetti, but it does that anyway with frameworks.
kinard 2 days ago [-]
There "demo here" url is broken, it's resolving as:
The power of web components is having the ability to develop complex front end without the need for a build tool in 2026. In 2008 when I got started with heavy javascript jquery was a must have tool to fill in for all the horrible browser api incompatibilites at the time. But because we are just developing custom elements with vanilla it works fine with vue and rust and all the others.
tancop 2 days ago [-]
> develop complex front end without the need for a build tool
zero build on complex front ends is disrespectful to your users. when you dont minify and code split you are basically saying "got a slow connection? tough luck, go wait for 10 seconds while this page loads 1.5mb of code that could be 5x smaller but i dont care enough to spend a couple minutes on a basic vite setup."
you might get away with it when its a mostly static page with a couple lines of script but when its a bigger app users will notice. "just write less code" is not an option most of the time. and tsc is also a build tool so if you take it strictly you either get no type safety or get stuck with awful looking jsdoc comments that take up space in your final script file.
austin-cheney 2 days ago [-]
I write in vanilla TypeScript. I do not have any build step in my application. Since Node now supports native type stripping I don't have a compile step either. I just write my code and then point node at the main file, and this even includes front-end code for the browser.
thisoneisreal 2 days ago [-]
Can you explain more about how the front end aspect works? I'm not clear how the front end code could by TypeScript without a build step, unless I'm misreading.
austin-cheney 2 days ago [-]
Node strips types on all imported code regardless of where that code executes.
root_axis 2 days ago [-]
Node doesn't run in the browser.
umvi 2 days ago [-]
Presumably Node is the server (back end), and when the browser requests a TS file, Node is stripping the types before serving it to the browser.
root_axis 2 days ago [-]
That presumption is wrong, and doesn't quite make sense if you think about it.
umvi 20 hours ago [-]
Why doesn't it make sense? I actually do exactly this in my own setup, but with golang instead of Node.
root_axis 8 hours ago [-]
I don't know what tooling you're using in go, but node does not do any kind of transformation to assets it serves over http. Running logic written in TypeScript on the front end requires some kind of bundler so that the browser can run the code.
umvi 7 hours ago [-]
You don't need a bundler, just a type stripper. And yeah you need a middleware to perform the type stripping, the server won't do it automatically, but it's like 10 lines of backend code. The basic flow would be something like:
1. Browser requests /js/foo.js
2. Server middleware checks if /js/foo.ts exists
3. If yes, server middleware strips types from the file before returning it
In golang I use the go package github.com/evanw/esbuild[1] to do type stripping on the fly. The middleware looks like this:
It only takes a few microseconds and I don't need any bundlers or tsc or anything like that. Everything on my frontend is 100% vanilla TS; I make changes directly to TS and then hit refresh in my browser and the changes are reflected instantly without needing a bundler or even node/npm for that matter. Note: for this setup to work, your front end TS has to use ES modules import/export which browsers natively support. If you try to use CommonJS or something like that, you would start needing a bundler again because browsers can't resolve "require" statements.
In node it should be even easier than Go because Node added native type stripping starting with v22[2]
But even on older versions of Node, a type stripping middleware would still be very easy to implement[3][4].
> It only takes a few microseconds and I don't need any bundlers
And yet you're using one. Esbuild is one of the most popular bundlers in the js ecosystem, your workflow is functionally identical to any other bundler workflow except that the example you provided is worse than the typical workflow because it builds the ts file on every request rather than just once when the source code changes.
umvi 3 hours ago [-]
> And yet you're using one
I'm using a TS type stripper API from a go package inside the server. I'm not actually doing any "bundling" which implies resolving imports, tree shaking, combining multiple files into one, minification, uglification, etc. I'm strictly stripping out types and serving what's left directly to the browser. This costs less than 1ms of cpu time on a cold load (and usually costs nothing because of front-end caching/etags)
Look, I don't want to argue with you. Just sharing my setup. I develop medical device software which means dependencies are very expensive because they incur regulatory burden. SBOMs and associated CVEs have to be tracked and reported to the FDA. My TS/golang stack means:
- My docker images can be from scratch or from busybox with a statically linked go binary
- My frontend can be vanilla TS with zero dependencies (npm or otherwise)
- Debugging is dead simple: set breakpoints directly in dev tools and it's WYSIWYG (no map files needed, etc)
- Feedback is instantaneous. If I change a file in TS and hit refresh, the change is reflected instantly (compare to bloated Vue/React shops I've seen where every change requires a 10 second frontend compile pipeline to run before you can get feedback in the browser)
austin-cheney 2 days ago [-]
I am aware and it’s not what I said.
root_axis 1 days ago [-]
You literally said "this even includes front-end code for the browser".
So what exactly are you referring to here?
austin-cheney 1 days ago [-]
I write all my application code in TypeScript, even if it is for the browser. I then import all that code into Node regardless of whether it will execute in Node. All code that will not execute in Node needs to be wrapped in a function for safety, because global references like "document" or "window" will not work in Node.
root_axis 1 days ago [-]
You write all your code in TS - great.
You run node with the TS support - great.
That doesn't explain how your front-end TS code is transformed into JS. You seem to be suggesting that node does it automatically, but it doesn't. The explanation of your setup isn't adding up.
austin-cheney 1 days ago [-]
> That doesn't explain how your front-end TS code is transformed into JS.
Node will do that at run time. Its automatic. Functions do not have to execute to receive this benefit. They just have to be imported. Ensure you are using a very recent version of Node.
root_axis 1 days ago [-]
Yes, but how does your http server deliver the imported code to the front-end? Are you using some type of streaming bundler that does real time builds? Something isn't making sense here.
austin-cheney 1 days ago [-]
On application startup I assemble together the various front end files I need and store this in memory as a string. When the server sees a request for the desired page I respond with the desired string.
Since I am not handcuffed by some giant framework I have maximum flexibility to do what makes sense.
root_axis 1 days ago [-]
> On application startup I assemble together the various front end files I need and store this in memory as a string.
So in other words, you created your own bundler?
Node isn't actually doing the work for you on the front-end.
austin-cheney 23 hours ago [-]
Again, I never said Node is did anything for the front end.
root_axis 19 hours ago [-]
Again, yes you explicitly did:
> I just write my code and then point node at the main file, and this even includes front-end code for the browser.
It sounds like you're just making stuff up.
austin-cheney 6 hours ago [-]
If you hire me as a consultant I will do it for you at $150 per hour.
root_axis 4 hours ago [-]
You said:
> I just write my code and then point node at the main file, and this even includes front-end code for the browser.
Then you said:
> I never said Node is did anything for the front end.
So which is it?
austin-cheney 60 minutes ago [-]
Since you need just a little help…
Yes, I push all my TS code through Node for type stripping. No, Node is not executing browser code. No, I am not suggesting Node is running in the browser.
For extra extra extra clarity importing functions in JavaScript does not execute them. They still have to be called for them to execute.
I am still willing to fix your code for a consultation fee.
brazukadev 58 minutes ago [-]
yeah this is a bit confusing. so you strip the types from the frontend and serve the .ts file as .js file? That's a transpiler/bundler.
1 days ago [-]
Gualdrapo 2 days ago [-]
I wish there was some sort of "use strict-typed" or something that let you use in-browser interpreted typescript
pianopatrick 2 days ago [-]
Well, you could use jsDoc to hold your types instead of writing them in typescript. The typescript compiler can still check types in jsDoc comments but you do not need a build step and the javascript you ship to the browser would be the same you write in your editor.
satvikpendem 2 days ago [-]
JSDoc is not as powerful as TypeScript types but that might be fine for your use case. However, if you are already using tsc I don't see why you'd care about a build step, and if you care that the JS in the browser is the same as the editor, tsc can do that too without minifying and changing the JS output, merely stripping the types instead.
hoppp 2 days ago [-]
I built some modules with jsDoc because I didn't want to have a build step but wanted type support.
Works fine.
teaearlgraycold 2 days ago [-]
It works really really well. No one should be writing untyped JS anymore.
zamadatix 2 days ago [-]
"use stricter";
tisdadd 2 days ago [-]
I have to admit that I really love web components ever since Polymer 1, and agree with the article sentiment (this post was starting to get to be a mirror of many of the authors thoughts, so cut it down)
It is very interesting watching the Web cycles, and found it curious how many people here were sad that typescript was not mentioned. There are some fun (though I suppose dangerous) things you can do without it, and I've found it has had very many instances not helped me where expected like a fully matured typed language has. And I've worked with a lot of people who just went I added types and don't know how to use generics.
I guess if you have it poorly implemented, then it's best to leave as JavaScript. And, web components you can keep things very simple... Which helps keep many errors down.
uzyn 2 days ago [-]
Author's EHTML "framework" reminds me of HTMX. https://e-html.org/html/vs-others.html misses comparison with HTMX. Curious on the similarities and differences.
pedro_movai 2 days ago [-]
Regarding Vanilla JS,
You don't need React: creating a minimal UI library:
Even better: vanilla TypeScript + golang middleware (esbuild) on the backend that converts to JS on the fly. Like vanilla JS but with all the benefits of a type system and no bundler or npm required.
bergie 2 days ago [-]
You still need a build tool, and that tool is likely broken if you need to return to the project in a year or two.
TypeScript benefits can be had without a build step by leveraging JsDoc.
mircerlancerous 2 days ago [-]
Any framework that requires me to learn custom syntax, is a problem in my opinion. I agree with the author that the browser is already the framework, and a powerful one at that. I don't really struggle with views and dom thanks to my own libraries, so maybe those without appreciate thw guilded gardens of these frameworks. Problem is that if these frameworks fall out of favour or stray from their original quality, you're stuck with worthless knowledge and maybe code as well
hahahaa 2 days ago [-]
React is an electric screwdriver. Real hassle: battery needs charging, need to insert correct bit, may need extendy bit for some jobs. But got an IKEA cupboard and not a simple shelf? Gimme that electric screwdriver!
In vanilla JS even small SPA projects can end up tangled or you are hand compiling what React would do for you for free.
Nit: in React events are events useEffect reacts to abstract state changes.
nashashmi 2 days ago [-]
VanillaJS ecmascript needs far more rapid development. Right now too often there are polyfills being suggested to avoid developing features into the browser. For example, react and vue and angular features should be standardized by now.
As for frameworks, we are not progressing towards AI-driven frameworks.
nnevatie 2 days ago [-]
Aka. I didn't like the N frameworks out there, so I invented 2 more. Now we have N+2...
jagged-chisel 2 days ago [-]
What’s the Idiomatic Vanilla JavaScript way to bind data and UI in a web browser?
tosti 2 days ago [-]
The whole thing boils down to creating objects (the constructor is built-in) and using functions on objects. Functions are objects, too. In fact, everything except primitive values are objects.
IMHO knowledge of C++, Python, or pretty much everything that's not a lisp variant, doesn't translate well to JavaScript.
There's such a nice language with its own silly warts, readily available to pretty much anyone with a computer regardless of form factor, being misunderstood by the vast majority of programmers.
umvi 2 days ago [-]
Web components, invoker commands API, etc.
austin-cheney 2 days ago [-]
What are you really asking? You use data to populate content or inform your logic.
jagged-chisel 1 days ago [-]
When the user changes a value in the UI, the data must reflect the change. When a value changes in the data, the UI must reflect the change. That’s “binding.” What’s the idiomatic way to solve this automatically?
austin-cheney 1 days ago [-]
I use WebSockets. If the user changes a value you have to send that changed value forward. If the value changes outside the UI you have to send it into the UI.
jagged-chisel 13 hours ago [-]
What does the binding look like in source code?
Do we hand-code every UI field with the code that updates the local model and then transmits it to the backend?
Or is there a way to make the boilerplate as small as possible, relying on one bit of code to handle synchronization between UI, local model, and server?
“Using WebSockets” doesn’t bind an interface element to its source of truth; it’s just the chosen transport to move the data. I’ll be sticking with a RESTy interface. But that doesn’t matter because the question is how is the binding implemented so that fewer mistakes are made synchronizing the data?
Hand coding every field’s binding logic is going to be error-prone.
austin-cheney 6 hours ago [-]
You are so thinking about this only from a framework perspective, as if you have no imagination. You can answer all your questions yourself by simply writing the code without a framework. Its not that scary.
It is as simple as I am suggesting, but only if you have actually done it yourself more than once. Whether or not your application is error prone is entirely on how you execute regardless of the tools in your toolbox.
owebmaster 2 days ago [-]
With webcomponent each tag is a component instance that can hold data and there are hooks for attributes change
LostInTheWoods 2 days ago [-]
This article misses the point of frameworks like Angular. Its never been about whether a framework is qualitatively better that vanilla or some other framework. The issue is when your codebase and your team reach a certain size you need the baseline, predictability and the guard rails that a framework provides. Otherwise you risk your project spiraling into chaos.
megous 2 days ago [-]
All projects spiral into chaos unless there's a person or more who try to reduce the growth of entropy, all the time, framework or not.
And these days, LLM agent will just re-use existing patterns if prompted correctly, regardless of who in the team is using it or whether or not there's a public well known framework in place or not. So consistency should not really be an issue anymore even in a team.
CM30 2 days ago [-]
Honestly, I've always thought that whether frameworks or vanilla JavaScript are better is very context dependent. If you're working on a complex UI where keeping everything consistent and understandable without a framework would be hell (like Google Docs or Gmail), then a framework like React is preferable. If you're working with a simple website that needs minimum interactivity, then vanilla JavaScript is probably the better tool for the job.
The issue is that much of the time, people seem to choose tools based on convenience/past experience, not whether it's actually the right solution to their current issue.
sourcecodeplz 2 days ago [-]
i think nowadays is more important than ever to understand why/how/when to use one technology vs another.
ask Codex to make you a website and maybe it will use React.
maybe you didn't need really need build steps, but whatever it works?
d--b 2 days ago [-]
I think OP is mainly right about this, but the tone of the article is going to annoy people very much. I believe many of us have done both the self-serving homemade framework and the industry standard framework. And many of us know the pros and cons of both approaches.
I don’t like react very much and dislike the other ones even more. Yet, it’d be stupid to say you can’t make them work. They come with a large community and pckages and solve a ton of problems that a homebrewed framework doesn’t even conceive of. And you can just start writing the stuff you need right away.
On the other hand, a homemade framework doesn’t require the extra overhead of knowing the framework, and maintaining it overtime. You don’t need to track down why the code gets run a gazillion times more than it needs to, you can debug through your events, etc.
They’re just different ways of doing things.
But mainly: react is a pain in the butt but if time is your constrain, it should get you to where you want to be faster than if you’re not using it.
curtisblaine 2 days ago [-]
Nobody says that React is great (also) because it's industry standard. If you pick up a React codebase you instantly understand how a component renders, where its state is, what its effects are, which components render that component etc. If it's React with a decent linter configuration, it's even easier. With a custom framework, on the other hand, you're at the mercy of who invented it. You have to find where state is, you have to trace where the state is "teleported" via broadcast, you have to understand where side effects are invoked etc. If the custom framework is as good as React, I'd still choose React just because it's a de factor standard.
brutaljokerz 2 days ago [-]
*vanilla typescript
dreamcompiler 1 days ago [-]
React was invented to make multiple DOM changes quicker and set up DOM event dependencies declaratively. Fine. Some websites benefit from this. Most do not.
Since React's invention, it has gotten more bloated, browsers have made living DOM changes a lot faster, and the vast majority of websites still only change one or two DOM objects in response to events. Those could easily be handled much faster with plain old AJAX. The latency overhead React adds to a website is quite noticeable and unnecessary. Airbnb.com for example would be a great deal more pleasant to use if they would ditch React.
The fact that React had to reinvent server-side rendering is all you need to know to see that React has jumped the shark.
dsego 11 hours ago [-]
It's not just react, there is a lot of bloat included in modern interfaces, things like telemetry, metrics, error reporting, heatmaps, etc. React was inspired by PHP rendering exactly because it is a much simpler model then the usual two way data binding models.
EugeneOZ 2 days ago [-]
The article is titled "Why Vanilla JS," but the takeaway seems to be "here are the custom abstractions I wrote."
65 2 days ago [-]
I like this article because it feels so pre-AI. This is what people were arguing about on HackerNews back in the day! How so very nostalgic it makes me feel.
But in response to the article: no, vanilla JS is a nightmare to keep your code organized, and battle tested frameworks do quite a good job at that. It's otherwise mostly a waste of time, or an intellectual exercise at most, to build an app with vanilla JS
LAC-Tech 2 days ago [-]
Based and Vanilla JS pilled.
I know posts like this get a lot of whinging, but you are 100% right. The browser is in itself a platform; frameworks are not like some kind of hyper abstracted Web Scrinting Language for people too important to deal with "raw" CSS/DOM. They're a an awkward, alternate abstraction, slow as molasses, and they leak like a sieve.
Those problems aren't 'solved'. The author has an implementation of a solution. It's one that they think is good, which is ace and I'm happy for him, but if he ever introduces a second developer to his project those 'solved' problems will become a point of friction. They'll go from 'solved' to 'solved, but in the wrong way' or 'solved, but not for this edge case', or 'solved, but why is the code so verbose?'
The massive advantage of a framework is that the people who choose it have agreed to share a solution to the common problems. This cannot be overstated - as soon as your team grows to more than one developer you move from 'solve the problem' to 'solve the problem in a way that people agree on', and that is far more complicated than just solving a problem. Sometimes you get lucky and work with people who think the same way as you, or with people who are willing to compromise on their ideal solution and accept yours, and then things still work, but if they're 'passionate' about being right then it's horrible, slow, and results in bad code.
A framework is an upfront agreement about how to build something. That has no practical advantage for a dev working alone. It's incredibly useful for two or more devs working together. Which framework doesn't really matter, except the ones with more devs behind them make it a lot easier to find people who've already accepted that way of working. That's helpful.
I agree with the problems you list, but I don't think a framework solves them. The same complaints can be made by the second developer because the first developer chose the "wrong" framework. Solved the wrong way, not covering the edge cases of your domain, too verbose etc.
Additionally a framework will likely be bloated and inefficient because they try to solve every problem for everyone, and you introduce a random breaking point where any framework update could in theory break your system.
Exactly this. There's so much fragmentation within the browser ecosystem that there is no guarantee your second developer will be comfortable/familiar with what the first developer chose. Even if you went with React you could be using state management they don't understand, a styling system they don't understand, etc... Even if you choose the most popular everything at the start of the project there is a lot of churn where things eventually fall out of favour.
I'd also be skeptical of web developers who work with React but aren't familiar with vanilla JavaScript. It's probably a good indicator that they aren't the best candidate but we can't all be picky.
yes it's still a framework, duh. it's just less abstraction than react etc.
Other people make different choices. That doesn't mean they're wrong.
People keep touting react etc but I swear every mobile ordering app I use lags like hell, just from recent example, and these can easily be built and maintained without a huge framework to "manage state" or "connect state to the view".
I don't doubt it. People make terrible websites with React.
However ... what might be happening is that you go to some websites, and some of them are great and others are terrible laggy garbage. When it's a bad one you open up devtools and see React, and that leads you to conclude that React is bad. But reality is that the good ones also use React, because most big websites use it.
Your reaction to the good ones is to assume they're well-built using whatever tech you happen to think is great (Rails, Vanilla JS, Vue, Svelte... whatever) but you're not actually looking. Hell, a great website isn't even a website, it's the experience of interacting with the business behind it. You don't even think about the tech when the website is actually usable.
Your reaction to the bad websites is to look under the hood, and you often find React.
That either means React websites are bad, or that React websites are good or bad, and it's not really React that's the issue. It's the team who built the site (and often not even the tech team; there's often some Product or commercial pressure that's driving the team to release something that's not really ready yet.)
I did an experiment recently, I actually wanted to launch a dashboard and picked React because I knew I could throw React + Tailwind + popular_component_and_charts_frameworks at Opus and get a decent result. But actually, I realized a lot of fairly simple button clicks had like a 100ms-200ms delay, and I just did not like it. I ported it to Java/Javalin with J2HTML and kept tailwind, and it's very snappy and works great. It's currently 96k lines of java ^_^
We shipped it like that. Turns out the computer's not fast and it does matter.
Because you think whatever you want to pretend your web software isn't MVC isn't solved doesn't mean it's true. Oh brother, MVVM, Model-template-view (no offense, Simon), come on.
You define resources on an HTML page, the browser loads them, renders a page, loads scripts, and makes AJAX calls.
You don't need build scripts for this. More over, these frameworks and build scripts DON'T SOLVE PROBLEMS. They move them. They want you to become a React developer. Not a software engineer who writes web software.
They don't solve routing, because you rewrite it every year. They don't solve bundling, because you change bundlers every year. They don't solve event handling, because they just move the chain of calls where you define the listener.
It's all a lie.
The vanilla approach is fine for a personal or toy project, but it's an unmitigated disaster for a project with even a moderately complex UI.
Eventually, the vanilla project becomes its own bespoke UI framework with a bunch of poor design choices because all the complexity that was dismissed as "artificial" eventually gets patched in using a rube-goldberg-machine approach to architecture.
This can be solved later, but is a lot harder when you have an entire application that needs to bee kept working, and almost trivial if you started with some reactivity built in.
In that case, the backend will likely have a class instancr representing it, with the first field being a discriminator on the class and the remaining fields being the details. And regardless of what the frontend does, the backend will revalidate always because you can never trust data sent from a frontend.
All that to say, maybe the form could be server side rendered, with an adaptor to convert a class definition into an html form fragment, and either embedding the js "rules" into the html itself, or making it a web component for containered usage.
Doing it this way is a big deviation from the current status quo, but I've found it to work very well and cut out a whole range of bugs. Plus it makes me think about what is truly client side state (no chance of staleness) vs server state cached in client to avoid repeat server calls (could be stale, leads to bugs).
React was invented because jQuery style state management collapsed into unmanageable code past a certain size
You don't need to remember how to properly line up useState/useEffect/useCallback and all.
You could just insert any simple state object and be ok with it, or insert a well-known state management library and it still works the same way.
For UI libraries they almost always have a vanilla option, and even better, if you are not working with google sheet level of stuff, vanilla element management is much much easier to work with.
And no need to talk about the style frameworks, they always work the vanilla way.
With some default vite configuration, nothing you need to worry anymore and the framework level stuff are simple and easy to understand and is totally manageable.
React’s complexity isn’t just components — it’s effects, state‑management conventions, data‑loading patterns, and the surrounding build ecosystem. If your UI doesn’t need those abstractions, adopting them early is pure overhead.
For these kinds of projects, React usually carries a much larger total cost than vanilla HTML + JS.
The “vanilla becomes a bespoke framework” claim assumes the UI will inevitably grow until it needs framework‑level abstractions. Most UIs don’t. React front‑loads complexity even when the UI is small, while vanilla only adds what the actual requirements demand.
A few helpers aren’t “reinventing React” — they’re choosing a simpler design avoiding numerous unnecessary abstractions, and with lower costs & complexity for the moderate apps they're building. It's a very valid architectural choice.
Vue is just a huge convenience over raw JavaScript for large, complex view. Sure, I don't get to do direct DOM manipulation, but when I write C code I also don't get to pick which variable goes in which CPU register. I accept giving up control that ASM would give me, for all the improvements that C brings on top of it, even if C just compiles to ASM and is an abstraction on top of it.
No, spreadsheets popularized reactivity. And the general point is incredibly weak.
Don't use frameworks and make your own? Sure, have your fun. But then try teaching your framework to your company of 1000 and see how quickly you realize your view of the "problems" are only a slice of the pie.
Do they need 1000 frontend developers?
Aside from the Giants maybe some consultancies or hire-firms have that many? But they use whatever the client uses. If you're not in the business of selling frontend development services then a big part of your competitive advantage is _being able_ to make technology choices that are more-optimal than the labor market's lowest-common-denominator slurry.
Between JS/ECMAscript being abandonware for a decade and CSS' historical immaturity (cross-browser layout, custom properties, more pseudoclasses, etc) the Web was more of a wild west "whatever you we can cobble together" place. So of course we built an entire toolchain ecosystem for all the cool new tools we would reinvent from scratch.
but Things Are Pretty Good these days. We even have the world's only fully system portable assembly language: WASM! And the browser's Web APIs are becoming something like the missing Standard Library (shoutout to Deno).
The author's point seems to be that we are past a tipping point where we need all that additional complexity. You don't _need_ a separate system of reactivity these days, you can write a (closer to pre-hooks React, even!) React-style component library with Web Components now.
Personally I would need for Type Annotations to be a fully supported part of the spec before I made the point to "use the platform" professionally. Until some market force causes the core web technologies to truly fork my skills are useful for life. It's like a pale shadow of how UNIX users must feel :')
I don't want to think of memory management in most projects, I want to focus on business logic, so I use Node.js instead of Rust, even if the latter gives me more control.
Similarly, I don't want to think of DOM management in most projects, I want to focus on data dependencies, so I use React instead of Web Components, even if the latter gives me more control.
The author frames this as artificial complexity, and that's the best framing I've seen. The browser has a particular presentation philosophy and the more you try to cover it up, the more awkward your code becomes at the edges.
The killer application of LLMs is their ability to inform and adapt to a particular API, and analyze the code that you write. They are garbage at producing functionality for which they don't have a thousand examples, but provide documentation and intent and they will help you fill in the gaps. This is the real 10x opportunity, and the best part is that you can still write all the code yourself.
I'm certain this doesn't just apply to javascript and the web. I predict that the need for frameworks will slowly go away.
A bit tired to see this...
No it's not. We do this all the time. It's as simple as using proper HTTP headers for your css/js/pictures/whatever. You can even have smooth page transitions now.
Multi-page applications are slow if you load in 20 libraries from 10 different CDNs, a page tracking system, a click tracking system, a "performance metrics" system, a chat bot overlay, an advertising platform, all the crap loaded by the ad intermediate, all the crap loaded by the ad itself, an ad "traffic quality" montor, a Stripe.com thing (even though this isn't a payment page), something from Facebook, something else from fbcdn...
The author is reinforcing the false dichotomy between using front end frameworks and hand-rolled JS, as if rendering data from JSON APIs is the only way to display information from the server.
Almost as an aside, he says
> Server Side Rendering is also no better, because while they can do certain things in more straightforward way, they break browser behaviour [...]
but he provides no examples or supporting evidence, so it's difficult to know what browser behaviour he's referencing. "SSR" is just how the web has worked since the beginning and it works very well. Maybe he's specifically talking about SSR as provided by Next? I've never used it, so I'm not sure what browser behaviour it might be breaking.
But yes the web has evolved since then and the HTTP protocol has newer versions and most apps don't serve as many users as Facebook.
If that means you have to make a small thing that is designed to do just the task at hand but to do it well, I am all for it.
I think the only frameworks that I have encountered that I felt were worth using were server side things like express where they had a very specific task to do and could isolate areas of behaviour.
It could be attributed also to typescript dominance of course, since people don't use plain js anymore.
As for the blog post, I agree, I also implemented my own js framework when I code in vanilla js and it works fine.
The problem is not inventing frameworks, the problem is that everyone invents frameworks, so people all know different things and they are hard to hire.
Of course, if you use old syntax you still deal with weird scoping and casting, but you don't have to any more.
Also, I think the framework churn has slowed considerably in the last 5 years.
This person re-invented form handlers, frameworks, ui helpers just to be able to do some basic things.
All power to you if you like it, its just funny.
https://e-html.org
Well played. You got me to visit your version of the thing you complained about. :clapping-emoji:
window.i = 0; // initialize all my for loops in one go!
Author then elaborates in the absence of using a common-knowledge framework you can create some tighter solution that achieves just the part you need. This is "fun" programming, and the author is suitably impressed with themselves for solving problems they created just by convincing themself not to use a framework. Sometimes that's fine, although I don't think there's much appetite for this anymore.
Article doesn't really elaborate on what "scaling" and "providing structure" means, I think it downplays the benefits because when you use <framework> you are really establishing ground rules for how all future developers are going to work on that software. You don't know exactly what they'll write, but you know they'll always gravitate towards the top 2 or 3 solutions for that framework at any given time.
When you bust out a bespoke solution that carves out that one thing you needed and does it oh so elegantly and perfectly, you're creating art but most of the canvas is left blank for future developers and they're effectively going to scribble on it with crayons.
Also - sometimes it is actually useful to make a mini-thing instead of bringing in enterprise messes.
Among the most critical realities to consider exist outside the product definition entirely, and have to do with the environment in which it will exist during and after development. These are things like plausible scaling curves and limits, code lifetime, team size, deployment options and preferences, etc. Others are things like available runway, team fluency and talent, available tools and licenses, etc.
One of the big eyeroll moments of the last 15 years or so was when folks started blindly cargo culting global-scale 10,000-engineer enterprise practices on projects that would obviously only ever be touched by 1-2 technicians and deployed on a far far far more modest scale. Instead of actively considering any of those environmental requirements above, "engineers" would try to treat every project as though it would someday service 10,000,000 DAU under the hand of dozens or hundreds of churning technicians.
Akin to the joke about some Americans who see themselves as "temporarily embarassed millionares", making foolish choices at their own obvious expense, many engineers during this era would seem to see themselves as "temporarily embarassed Facebooks".
In countless cases, this was simply very dumb and very wasteful and at best amounted to inadvertent (or perhaps intentional) resume-padding for the people involved, while their projects bloated and sagged and lurched under unwarranted complexity.
Sometimes (in fact: often), just doing the thing well with simple, clear, stable tools -- and nothing more -- is the right choice.
Stronger: that should be standard operating procedure. Unless there's a pressing need (if not absolute necessity) to do otherwise.
Not too mention how damaging it all is to environment in exacerbating the climate catastrophe.
Web Components and vanilla JS scale just as well. Been doing this for ages.
While I’m not the biggest fan of Nextjs for my own solo projects, I really enjoy using it at work. Leaning into the opinionation it provides/encourages keeps my team from bickering too much about how to structure things.
It’s really nice to say “this is the idiomatic way of doing it according to the docs” and for everyone to nod their head. Whereas pages in our legacy PHP codebase look completely different depending on who implemented them.
Folks learn about how to use modules and libraries?
Front ends works like this - main app split into few smaller ones callable from a menu. Each sub-app is dynamically imported module (no need for building, code mutilation, direct dependency etc). Sub-apps in turn can consist from the other sub apps. Each can be worked on completely independently by different team member with virtually no interaction needed. Apps can share some approved libraries (like for graphics etc) and HTML components responsible for particular bits and pieces. Components and libs go into common pool. Once component is in a pool modifying behavior is punishable by death. Only internals. If change is breaking then simply new version is developed and deployed.
The whole thing is super scalable organization wise (nearly everything is decoupled) and resource wise as well since everything is loaded strictly on on need basis.
And sure, there is a build step. I have never felt like this was a problem with Svelte, but then I don't have experience working on a colossal Svelte app. Does it become one?
Especially nowadays with LLMs, the team would benefit more from the LLM innately knowing a widely used library/framework than having to spend context each session teaching the agent your custom setup through context files and skills.
Plain JS is also a lot better with AI. I don't recall Claude ever making any mistakes in terms of getting the type wrong with plain JS since I started using it. It's just not the kind of mistake that AI makes.
I feel somewhat vindicated by this. I've been saying for years that coding isn't the hard part, type correctness isn't the hard part. I also made a point that complex interfaces are a greater danger and that Typescript tends to encourage people to design complex interfaces... And look, this certainly seems to be reflected in the training data because my AI token usage at work (Typescript) is far greater than on my side projects for the same task complexity.
This is kind of proving my point that plain JS code is better architeted overall than Typescript code... It makes sense to me, any complex plain JS code MUST be well architecture because JS is unforgiving. The spaghetti doesn't go very far in JS.
Just use server side template rendering with HTMX. LLM can see server side request flow better anyway.
As for offline, yeah, my Internet web page doesn't work offline. Shocker.
That's really too bad honestly. What about your users who want to use your site when they're offline? Sympathy with those users is why I made sure that my site works well when offline.
Web apps that are valuable to use offline also tend to be the kind that really do warrant client-side logic and rendering (a spreadsheet web app is a classic example).
If the site's focus is providing information (e.g. Wikipedia), then working offline really just means loading all the backing data into the browser, which quickly becomes impossible.
I'm sure there are cases where offline availability is a huge plus (your site might be a good example), I just don't think it's universally applicable.
Also with the developer disruption of agentic coding AI, the arguments for using vanilla JS is even stronger. Code reviews of code/solutions is much easier. Scoping of code paths for each server-side render templates is easier. The AI does all the boilerplate coding, while keeping it readable and debugable. Implementing design patterns is just common computer science stuff, and the coding agent is pretty good at it.
I also what to mention, as a business owner, and boss of a startup. All developers here work with vanilla javascript. They were first surprised, but today they prefer it by a huge margin because of the simplicity and zero dependency and non existing build steps. The web browser is the framework, you need another abstraction over the web browser.
https://cdn.guseyn.com(/mp4/desktop.mp4)
Instead of
https://cdn.guseyn.com/mp4/desktop.mp4
zero build on complex front ends is disrespectful to your users. when you dont minify and code split you are basically saying "got a slow connection? tough luck, go wait for 10 seconds while this page loads 1.5mb of code that could be 5x smaller but i dont care enough to spend a couple minutes on a basic vite setup."
you might get away with it when its a mostly static page with a couple lines of script but when its a bigger app users will notice. "just write less code" is not an option most of the time. and tsc is also a build tool so if you take it strictly you either get no type safety or get stuck with awful looking jsdoc comments that take up space in your final script file.
1. Browser requests /js/foo.js
2. Server middleware checks if /js/foo.ts exists
3. If yes, server middleware strips types from the file before returning it
In golang I use the go package github.com/evanw/esbuild[1] to do type stripping on the fly. The middleware looks like this:
``` return esbuild.Transform(string(fileBytes), esbuild.TransformOptions{ Loader: esbuild.LoaderTS, Format: esbuild.FormatESModule, }) ```
It only takes a few microseconds and I don't need any bundlers or tsc or anything like that. Everything on my frontend is 100% vanilla TS; I make changes directly to TS and then hit refresh in my browser and the changes are reflected instantly without needing a bundler or even node/npm for that matter. Note: for this setup to work, your front end TS has to use ES modules import/export which browsers natively support. If you try to use CommonJS or something like that, you would start needing a bundler again because browsers can't resolve "require" statements.
In node it should be even easier than Go because Node added native type stripping starting with v22[2]
But even on older versions of Node, a type stripping middleware would still be very easy to implement[3][4].
[1] https://pkg.go.dev/github.com/evanw/esbuild
[2] https://nodejs.org/api/module.html#modulestriptypescripttype...
[3] https://github.com/bloomberg/ts-blank-space
[4] https://esbuild.github.io/api/#js-async
And yet you're using one. Esbuild is one of the most popular bundlers in the js ecosystem, your workflow is functionally identical to any other bundler workflow except that the example you provided is worse than the typical workflow because it builds the ts file on every request rather than just once when the source code changes.
I'm using a TS type stripper API from a go package inside the server. I'm not actually doing any "bundling" which implies resolving imports, tree shaking, combining multiple files into one, minification, uglification, etc. I'm strictly stripping out types and serving what's left directly to the browser. This costs less than 1ms of cpu time on a cold load (and usually costs nothing because of front-end caching/etags)
Look, I don't want to argue with you. Just sharing my setup. I develop medical device software which means dependencies are very expensive because they incur regulatory burden. SBOMs and associated CVEs have to be tracked and reported to the FDA. My TS/golang stack means:
- My docker images can be from scratch or from busybox with a statically linked go binary
- My frontend can be vanilla TS with zero dependencies (npm or otherwise)
- Debugging is dead simple: set breakpoints directly in dev tools and it's WYSIWYG (no map files needed, etc)
- Feedback is instantaneous. If I change a file in TS and hit refresh, the change is reflected instantly (compare to bloated Vue/React shops I've seen where every change requires a 10 second frontend compile pipeline to run before you can get feedback in the browser)
So what exactly are you referring to here?
You run node with the TS support - great.
That doesn't explain how your front-end TS code is transformed into JS. You seem to be suggesting that node does it automatically, but it doesn't. The explanation of your setup isn't adding up.
Node will do that at run time. Its automatic. Functions do not have to execute to receive this benefit. They just have to be imported. Ensure you are using a very recent version of Node.
Since I am not handcuffed by some giant framework I have maximum flexibility to do what makes sense.
So in other words, you created your own bundler?
Node isn't actually doing the work for you on the front-end.
> I just write my code and then point node at the main file, and this even includes front-end code for the browser.
It sounds like you're just making stuff up.
> I just write my code and then point node at the main file, and this even includes front-end code for the browser.
Then you said:
> I never said Node is did anything for the front end.
So which is it?
Yes, I push all my TS code through Node for type stripping. No, Node is not executing browser code. No, I am not suggesting Node is running in the browser.
For extra extra extra clarity importing functions in JavaScript does not execute them. They still have to be called for them to execute.
I am still willing to fix your code for a consultation fee.
Works fine.
It is very interesting watching the Web cycles, and found it curious how many people here were sad that typescript was not mentioned. There are some fun (though I suppose dangerous) things you can do without it, and I've found it has had very many instances not helped me where expected like a fully matured typed language has. And I've worked with a lot of people who just went I added types and don't know how to use generics.
I guess if you have it poorly implemented, then it's best to leave as JavaScript. And, web components you can keep things very simple... Which helps keep many errors down.
You don't need React: creating a minimal UI library:
https://pedroth.github.io/?p=post/NoNeedReact
TypeScript benefits can be had without a build step by leveraging JsDoc.
In vanilla JS even small SPA projects can end up tangled or you are hand compiling what React would do for you for free.
Nit: in React events are events useEffect reacts to abstract state changes.
As for frameworks, we are not progressing towards AI-driven frameworks.
IMHO knowledge of C++, Python, or pretty much everything that's not a lisp variant, doesn't translate well to JavaScript.
There's such a nice language with its own silly warts, readily available to pretty much anyone with a computer regardless of form factor, being misunderstood by the vast majority of programmers.
Do we hand-code every UI field with the code that updates the local model and then transmits it to the backend?
Or is there a way to make the boilerplate as small as possible, relying on one bit of code to handle synchronization between UI, local model, and server?
“Using WebSockets” doesn’t bind an interface element to its source of truth; it’s just the chosen transport to move the data. I’ll be sticking with a RESTy interface. But that doesn’t matter because the question is how is the binding implemented so that fewer mistakes are made synchronizing the data?
Hand coding every field’s binding logic is going to be error-prone.
It is as simple as I am suggesting, but only if you have actually done it yourself more than once. Whether or not your application is error prone is entirely on how you execute regardless of the tools in your toolbox.
And these days, LLM agent will just re-use existing patterns if prompted correctly, regardless of who in the team is using it or whether or not there's a public well known framework in place or not. So consistency should not really be an issue anymore even in a team.
The issue is that much of the time, people seem to choose tools based on convenience/past experience, not whether it's actually the right solution to their current issue.
ask Codex to make you a website and maybe it will use React.
maybe you didn't need really need build steps, but whatever it works?
I don’t like react very much and dislike the other ones even more. Yet, it’d be stupid to say you can’t make them work. They come with a large community and pckages and solve a ton of problems that a homebrewed framework doesn’t even conceive of. And you can just start writing the stuff you need right away.
On the other hand, a homemade framework doesn’t require the extra overhead of knowing the framework, and maintaining it overtime. You don’t need to track down why the code gets run a gazillion times more than it needs to, you can debug through your events, etc.
They’re just different ways of doing things.
But mainly: react is a pain in the butt but if time is your constrain, it should get you to where you want to be faster than if you’re not using it.
Since React's invention, it has gotten more bloated, browsers have made living DOM changes a lot faster, and the vast majority of websites still only change one or two DOM objects in response to events. Those could easily be handled much faster with plain old AJAX. The latency overhead React adds to a website is quite noticeable and unnecessary. Airbnb.com for example would be a great deal more pleasant to use if they would ditch React.
The fact that React had to reinvent server-side rendering is all you need to know to see that React has jumped the shark.
But in response to the article: no, vanilla JS is a nightmare to keep your code organized, and battle tested frameworks do quite a good job at that. It's otherwise mostly a waste of time, or an intellectual exercise at most, to build an app with vanilla JS
I know posts like this get a lot of whinging, but you are 100% right. The browser is in itself a platform; frameworks are not like some kind of hyper abstracted Web Scrinting Language for people too important to deal with "raw" CSS/DOM. They're a an awkward, alternate abstraction, slow as molasses, and they leak like a sieve.