For one thing, I just genuinely think WebComponents are a badly designed API that is weird and hard to use (how many people are using WebComponents without at least Lit, if not something much bigger?), and React is a relatively well-designed library that isn't really that bloated. There's not really much of a point in trying to argue since this is inherently subjective and people with different values are going to irreconcilably disagree. But, if you don't respect that some people hold this position, we're not going to make any progress towards a consensus.
On the note of <dialog>, I recently tried to use <dialog> in a (React) application, and it did work pretty well, but I also found that in Firefox it is only practically possible to do a fade-in animation, not a fade-out one. That isn't really a critical issue for me, it is just an animation after all, but I find it unfortunate. I also find <dialog> to be a weirdly shaped API too: I don't really hate it, but I don't love it either. It feels awkward.
I find this implicit view that developers that, for example, prefer React over WebComponents are making a suboptimal choice to be rather condescending and not really in the spirit of trying to see things from the other side. Wouldn't you want to focus on the strongest arguments and not the weakest ones? Maybe you've literally never heard anyone complain about WebComponents or Shadow DOM, but if so, I find that surprising. Certainly here on HN, I've seen a fair bit of WebComponents hate.
I do, FWIW, realize that I've particularly focused on WebComponents, which this article doesn't actually name directly. But, I assume we're not talking about ditching React to implement our own component framework on top of the traditional DOM APIs, because that's what React already does...
> I just genuinely think WebComponents are a badly designed API that is weird and hard to use
This was exactly what sprang to mind as soon as I saw the title. I’ve been writing front-end code for over 25 years now, and exactly two things in that entire time have made me miserable enough to think about stopping: Internet Explorer 6 and web components. Every time I try to just “use the platform” it makes me miserable and I end up demotivated and stop working on whatever side project I chose to try again with. And I otherwise like the web platform! I’ve been building with it since there was nothing but the web platform. But web components kill my enthusiasm for it stone dead.
Even now in the age of agentic development, AI trips over all the same footguns in web components that humans do. It just seems like everybody involved has been adding to the standards with “yes, and…” without ever thinking about how it will be used by web developers in practice.
People are using things like lit and react not because web components suck but because they want something reactive (declarative UI bound to app state).
Web components are lower-level than that -- they can be one building block for this (e.g., lit), but don't accomplish it on their own.
I have stubbornly avoided React. When native WebComponents became a thing, I figured I'd try them out on a small internal site I maintain. It was very slow. In an effort to reduce a bit of duplicate code, my site when from loading instantly to having a noticeable load time. Having to employ tricks to try and optimize and speed up the most basic implementation of a built-in feature seemed like the wrong move, so I ditched them all together and reverted back to my old structure.
What do you not like about WebComponents?
Say we want to make an icon that when clicked shows how often it was clicked. The webcomponent code seens quite sane to me:
class HelloIcon extends HTMLElement {
connectedCallback() {
this.clickCount = 0;
this.innerHTML = `
<button class="icon">:)</button>
<dialog>
<p>Hello, I was clicked 0 times</p>
<button class="close">Close</button>
</dialog>
`;
const icon = this.querySelector('.icon');
const dialog = this.querySelector('dialog');
const closeBtn = this.querySelector('.close');
const dialogText = this.querySelector('p');
icon.addEventListener('click', () => {
this.clickCount++;
dialogText.textContent = `Hello, I was clicked ${this.clickCount} times`;
dialog.showModal();
});
closeBtn.addEventListener('click', () => dialog.close());
}
}
Try it here:https://plnkr.co/edit/0XUOLyM52xfFiIBu?open=index.html&previ...
What about the web components APIs are bad, and how could they be done differently given the reality of the existing platform?
It’s surprising how bad the API is. Shadow DOM makes just about everything worse. Our frontend org opted out of even using Lit, so we get the raw stupidity of the whole idea.
Style encapsulation? You get that, but not fully, and good luck finding out which parts you don’t get.
State management? Back to query selectors, which btw work worse and need workarounds when reaching into the shadows. We went with DOM-as-state. I don’t want to talk about it.
Slots? After coming from a modern framework, slots are a clear step backwards. In React you can pass a component as a prop but in the shadow DOM world, you have to signify it with HTML. Multiply it by several slots and you get a lot of verbosity just to match the behavior.
Yet to mention using the platform directly means losing so much work around static verifiability. No one has to talk about this anymore, but sticking religiously to the platform by strictly using addEventListener means you can’t require event handlers to exist for any of your elements. People forget this, but the browser’s default way of letting you do anything is an enormous footgun for reliability.
Learn from our frontend org’s mistakes. Run, don’t walk, away from it.
How can you say react isn't bloated it requires a full download on first website visit, web components are browser native, not saying they're better, but to say react is not bloated is an affront , there was a time where people were carefully deciding on whether or not to include jquery.
WebComponents were created out of spite for react and are the composability equivalent of medieval artist drawing horses that look like they had never seen an horse
Stencil or Lit are basically required, yeah.
I don't understand why browser makers don't just steal the API from popular solutions like React honestly. That's "fair use" since Oracle v Google afterall.
Only if you mean React before they went crazy with hooks and "use whatever" magic strings.
I put up with it, because plenty SaaS products favour Next.js and React as their only extension SDK.
I would never pick it up freely, all side projects with Web are VanilaJS, coupled with what is available on Java, .NET and PHP.
> React is a relatively well-designed library that isn't really that bloated.
I am one of the people who irreconcilably disagree. I think svelte and solidjs are - obviously - technically superior. But it leaves the question of why react is still so popular. I think the biggest reason is all the non-technical aspects of react:
- They have excellent documentation. And have, from day 1.
- They produced videos, sample projects, and all sorts of "getting started" documentation.
- They ran react conferences, teaching everyone who would listen about "1 way data flows" and pretending like they invented FP.
The amount of hype around it made it really feel like the next big thing. Between the very well funded react team and the outside developer community, there was real momentum. People learned it in droves. Taught students. Built websites with it. When react's poor design choices caused issues (and there were a lot of issues), then you were blamed for holding it wrong. (Component classes, state, CSS, hooks, webpack and babel taking ages, big bundle sizes, slow re-renders, and so on.)
By the time the next generation of JS frameworks broke onto the scene, there was a collective moan from the community. "Oh no, not again - we just relearned how to make websites." React was the wave, and in its wake we all had Framework fatigue.
Software doesn't get popular without a lot of work by dedicated people. I really admire the work standards bodies do. But they rarely bother to take the time to produce documentation, videos, tutorials, starter projects, blogs and podcasts and all the rest of that work.