A few years ago I wrote an article suggesting that Web Components might not be the most beneficial direction for Web development to head.
...
For further actions, you may consider blocking this person and/or reporting abuse
Hmmm... I'm not convinced. I think you're trying to make web components more than what they are - custom elements with sandboxed styles and some js logic to them.
I, for one, thinks that the frameworks might not be the future. The sentiment I get more and more is that frontend is in a complete mess because of frameworks and the overwhelming abstraction, keeping us away from web standards. Web standards which are closing the gap and offer native solutions to challenges framework came to solve.
I say it is time to consider going back to square one.
He doesn't, but other people do, and that this can become a problem is the point of this whole article.
On the contrary, it seems that a lot of frameworks seem to converge on the same pattern of state signals effecting DOM changes through composable components.
And here you're making the same mistake that becomes a problem. Web components are an abstraction that can be used for such solutions, but they are not a solution in itself. Also, their previous design decisions now become a burden to development in other directions.
In what ways? The whole point of this article was that web components are not solving the same problems frameworks are, so is there any other standard you are referring to which is closing the gap?
Have you seen conversations in the Web Components Community Group discord (which by the way has a different logo than the one the article is catching on fire)? We're very much solving similar problems, but user land frameworks are, of course, always a step ahead in helping figure out those problems.
Of course. I've been involved on a few of those discussions on the past. I want to quote this from my article.
I have no doubt that in many cases similar systems to those in frameworks can be made. Context API is perfect example. But due to the constraints of being DOM Elements the implementation differs in ways that make them less portable or difficult to make compatible with what the frameworks are doing. So we are stuck with something that can't be adopted by the framework and is generally incompatible.
But if an abstraction is not compatible with Solid's, it's ok, maybe it is compatible with WCs. Yeah Solid context API is not designed for Custom Elements, but that doesn't preclude a nice context API from existing for custom elements.
It is true that Solid context API is not portable for custom elements in general, but that's ok. Even without a context API, custom elements are useful. And there are context APIs that work with custom elements in general, and also context APIs specific to custom element frameworks.
At the end of the day, maybe no pattern can work for everything. A context API for custom elements may definitely not be compatible with Solid or vice versa.
Following some conventions for example, Lit's context API, or this simple context example I made in the Skate.js days, can work reasonably well when sticking to the same convention in a single app.
It's not like everyone needs the same context implementation. Solid's is only good for Solid users, it will never be good for other frameworks or even custom elements. The custom element contexts at least have a chance of working across multiple frameworks, but that's still not good enough across multiple CEs with differing context APIs, and maybe that'll be impossible forever.
Ultimately custom elements are more compatible than you are making them out to be.
For example Lume 3D elements work in Solid, React, Vue, etc, and even provide faster declarative data management than react-three-fiber. The abilities it unlocks across all frameworks now and in the future is magnificent, and truly is a testament to what is possible with them.
Like just because I cannot use a Solid context with Lume custom elements is nowhere near a problem that can outweigh benefits.
Making react-three-fiber work in Solid is a lot more difficult, and vice versa for solid-three.
If Lume gains a killer feature everyone wants, it'll automatically work everywhere and the cost will be small compared to the gain in abilities.
Completely slamming Custom Elements is too heavy handed. They're already here to stay and the best frameworks will ensure they work well in their systems (not saying non-custom-element frameworks needs to output custom elements, just that custom elements need to be easily consumable in them, that's where the major benefits are because there are already other frameworks for writing them).
The user experience matters the most, and if I can out together a 3D application in any non-CE framework and it works out fine by all standards of what a fine app is, then it means the custom elements did their job.
Frameworks are always the future because people will always build abstractions on top of what they have to make their lives easier.
You don't get to claim I'm making them out to be more than they are and then claim they are a native solution to challenges frameworks came to solve. That is trying to make them more than what they are.
More accurately I'm saying they aren't more than what they are and they don't solve what frameworks set out to. If anything they are more of a hindrance. Which is why when going back to square one I'd consider if they have any worth at all. Many frameworks were on board early days. As I said they were why I created Solid.
But in hindsight I better understand the degree I was mistaken. I grew from seeing them as a useful tool to something unnecessary. But now I think them detrimental to the web on average. We already built frameworks in a world Web Components were the future. I wish I could turn back the clock and try again in a world they were not.
“If anything with compilers and advancements in build tools, we are moving more in the direction away from components being anything more than a Developer Experience consideration.”
If component obsession is the core issue then it doesn't matter if it's part of a framework or a web standard.
I mostly second this; I see why frameworks are cool, but they are specifically built to hide the browser APIs in a world where said APIs are becoming more and more powerful.
Web Standards are ever evolving, but they are nowhere near to reach the DX of frameworks like Solid or React. Authoring reusable pieces of content using only DOM APIs is laborious and scattered.
I demonstrated this few years ago to a client having the same opinion as you by writing the same app in Web Components, HTML templates and React. Needless to say the comparison of framework vs non-framework is not pretty nor something an average developer would like to maintain, even though I tried to make it as declarative as possible.
If we went to square one, we would immediately start creating abstractions to simplify operating the DOM APIs and move to a more declarative fashion. Eventually, we'd end up at the same place we find ourselves in currently. It's not a perfect state, but miles ahead from 10 years ago with frameworks providing much of the needed support.
"I demonstrated this few years...", I kinda lost you in "a few years ago" ;)
The web standards are constantly and rapidly evolving. Yes, you can always abstract them for better DX but I'm talking more about the concepts of SPA's vs. MPA, reactvity, SSR and more... The place frameworks take in these areas today, moving away from the native apis the platform supplys will be diminished over time, IMO.
Not much has changed in the past few years with respect to the DX of custom elements. From what I've seen over the past decade, custom elements have actually been very slow to evolve. Care to elaborate?
It depends™, but web components are a blessing when building any kind of universal UI that should be used across frameworks, vanilla JS, whatever. Personally, I don't like the native custom elements API (or API family, realistically). And, I'm really happy that things like solid-element exist since I get to compile down from a DX I like to something I can use across the board. Does it always translate well? No. Not by a longshot. Does it matter? I don't think so (again, depending on what you're building). It comes with a bunch of tradeoffs - type declarations are awkward, imports are awkward... But it works.
Here's a practical scenario: supertokens.com, in general, has two ways of integrating with anything—our pre-built UI (currently in React, with a compiled universal version) or DIY (just use the SDK). We'd like to support everything out there, and some users like having a set of pre-made components to just drop in and call it a day. So, we're faced with a choice - either try to support every framework under the sun in their native "language" (which requires an army of engineers), or go for something like web components. I think that for those use cases, it's an easy compromise to make. There are other, IMO, very valid uses of web components -shoelace.style comes to mind.
But! I don't think frameworks should standardize on web components (in any sense). Provide a way to use them, sure. The less awkward the better. Each should ideally also have a path to produce them if needed (as Solid does, for example). As much as I love standards, Web Components aren't the silver bullet some of us hoped them to be.
Excellent read, thanks :)
Thank you for your response. A lot of this sprung from my realization just how much of a cost supporting Web Components properly has had on the library. And how it is basically endless. We doubled the size and complexity of our event delegation code in the last release (1.9) just to handle Shadow DOM better and it still falls flat for many cases because of how Shadow DOM is designed. It's not within our means to fix, but when we say we support Web Components people come to expect it. I could delete pages of code if I didn't care to support Web Components I could simplify many things.
Instead we are here. I can just picture when the push for SSR web components becomes a thing at the detriment of performance/code complexity there. Are there no limits to pushing something which brings us no direct benefits and pushes the cost on to all our users?
I don't think this is a strong argument against Web Components because you can easily flip the statement and still holds true: "We doubled the size and complexity of our event delegation code [...] just to handle Shadow DOM better and it still falls flat for many cases because of how Solid.js is designed."
I get that it's a lot of work for the Solid team to make WCs work, but you're also the one who created a mental model that is dramatically different than a piece of the web platform. You have absolutely the choice not to support WCs, but I don't think it's a case against WCs as much it is a case against frameworks.
FWIW, I personally avoid the Shadow DOM. Sure, it solves some problems but opens an entire set of new problems (and not just problems specific to frameworks). I won't even pretend I can fully understand the struggles that FW authors have when trying to support it. But, as a user of both Solid and web components, may I suggest that this may be made easier by setting users' expectations more explicitly?
For me, what's currently in Solid works well enough - I can use web components inside Solid and can author web components with Solid. I don't imagine that's everyone's experience, but maybe that can be improved by better docs and examples (thus, hopefully reducing the burden of having to support every edge case under the sun). The "golden path", for me, would be something like (and I'm taking Solid as an example here, but I imagine this can be applied across the board):
Ultimately, I realize there's a point when all of this complexity stops making sense to support due to the amount of work authors pay, and the bundle price users would pay. I'd be happy to help in making this better, however. To put my money where my mouth is, I'll start working on this one github.com/solidjs/solid-docs/issu... starting tomorrow.
This is a really interesting point and one that I wish I hadn't missed when I first read this. I take it Solid does automatic event delegation because of the perf benefits? I know there was some debate about this in
js-framework-benchmark
.In LWC we definitely don't attempt to solve this problem, which makes our implementation simpler at the expense of forcing the component author to do event delegation themselves if they want to improve perf. OTOH I crunched the numbers a few years ago, and event delegation is still a clear perf win, although on the order of ~30ms for 10k elements, so not necessarily huge.
I think this is true from a 10000 foot view. It may appear to work, but when you look closer you will find that it may not work well, or at all. This is particularly true with React.
Consider a custom nav element,
<custom-nav-item>
with a built-in<a>
tag. If you try to use this element with Remix, React Router, Next.js, Gatsby, etc... you will quickly find that the internal<a>
tag is incompatible with most of these. They each use a specific<Link>
component that is responsible for enabling clientside routing (i.e. SPA mode). You can't nest an<a>
tag inside another<a>
tag, so something like<Link><custom-nav-item /></Link>
is not a viable approach. I actually don't think there is a viable approach that doesn't result in invalid HTML. In this case, the main issue is nesting an<a>
tag inside another<a>
tag.I would argue that this is not working, and therefore not viable. And this is but one of many issues when it comes to integrating web components in modern frameworks.
While I get your point, you can still just attach an onClick and pass make the
custom-nav-item
just triggernavigate
, right? That said, I don't think I'd ever go for a custom nav item when using a framework. It just doesn't feel like the kind of a problem that WCs are good for.The onClick approach is an issue for several reasons:
<a>
tag already covers for us.Completely agreed. I am wary of evangelists that are extremely pro web components (or for that matter, any technology) to the point of blind dogmatism. This is not healthy for any engineering team. They are not the best fit for many use cases, particularly with frameworks, and that's what the author is getting at.
Then, I don't think we disagree? :D
The point I was trying (perhaps unsuccessfully) to make is that WCs do have some good use cases. They aren't many, and they come with compromises - but those cases exist. Two come to mind (there are probably more):
Agreed haha.
I use web components more as a progressive enhancement, usually. I steer clear of the shadow DOM completely. What I would prefer is a
traits
attribute that I could put on an element to enhance that element.So, if I had a
dialog
element I could addtraits="x-modal"
that would make it so once I add thedialog
element to the page it would be treated as a modal without me actually having to callshowModal()
on the element.Or maybe something like
<select multiple traits="fancy-select">
that would turn myselect
into a fancyselect
element that you could see above it all the items you've chosen and could x them out easily in a more UI friendly manner.What is annoying about frameworks is that you have all these cool libraries that are locked behind the frameworks themselves, but can't use if you want to use a different framework or no framework at all.
Also, with frameworks, especially ones like React, they don't play nicely if you want to outside the box. Maybe I would part of the page to work with HTMX. Well, that will be pretty tough to do with React (I've tried it).
So, that's typically how I use web components. I use them to progressively enhance my page with an HTMX-like framework. It works pretty nicely. Now, if you have a page that requires to have a lot of local state and changes I'm all for frameworks and I will not likely reach for web components. But most of my pages are pretty simple and I try to keep them that way.
Granted, recently I did build a little app with just web components that could also use a framework (the framework came in with 150 lines less than the web component solution - I just like the control).
Yeah there is "is" for native element extension, but I get "traits" would be more powerful. That all being said I agree that would have been less obtrusive. Doesn't handle all the cases WCs envision though. Slotting and handling of DOM children is a difficult problem so I get why the Shadow DOM exists even if it is the source of a lot of the problems.
I think it is ok React wants to control its area of the page. It gives it incredible power there that otherwise would be very difficult to accomplish. Not every one needs that power but the boundary is clear and thus swappable.
I can get why an HTML interface with something like HTMX is desirable. It is less visual overhead than adding an id to a div and running a small script. No argument with the ergonomics. Just the impact it has had on the rest of the platform has been significant and that concerns me.
Yes, and the developers at Apple have said they won't implement the
is
attribute so you have to always have a polyfill for it. Yes, I agree that web components are much more powerful. I just want something simpler. Withtraits
I could have multiple different enhancements on a singe element.Thank you for your reply!
Custom Elements and Shadow DOM are available a la carte. Some don't realize that non-Shadow DOM Custom Elements are common. GitHub has a collection, some of which don't have a shadow DOM. Here is one: github.com/github/text-expander-el...
I am bullish on Web Components, because I see them mixing better than two non-Web Components frameworks. I don't see any obstacles to it being widely adopted. If you're careful to use slots, you can put the desired elements in the light DOM, even if they're wrapped in several components containing shadow DOMs.
If you think that Web Components are being adopted very slowly due to their limitations, I encourage you to take a look at some libraries like from Salesforce and SAP. You may not like the workarounds, and think it's just hype driving them, but it gives me the feeling that Web Components are at least a big part of the future. Here's a label web component with for=id being handled by a click event: github.com/SAP/ui5-webcomponents/b...
But is mixing multiple frameworks ever a place you want to be. Sometimes friction to bad ideas is a good thing. Sometimes limitations breed innovation.
As I said in the post there are always solutions to problems but ever so often you need to ask what you are gaining from it.
I am not criticizing their adoption, or claiming people aren't using them. Or suggesting even that they are implemented completely terrible. I'm stating that they bring a cost to the platform that is regrettable over a benefit that is mostly superficial. I feel they now they were the wrong abstraction but that ship has sailed from a standards perspective. The world they promote is no less bloated than what we have today except we pretend things are fine.
It's rarely a matter of "want", more like of "have". Meaning I can't reuse a React component in an Angular application: I have to recreate it.
Heck, I'm not even certain that the same component will work with different versions of the same framework!
That's not the case for Web Components, and that's a clear winner.
“The Rule of Three” (Biggerstaff, T. and Richter, C. (1987) Reusability Framework, Assessment, and Directions):
• You must have looked at at least three systems to understand what is common across them (and therefore reusable)
• It takes three times as much effort to make something reusable as to make it usable
• You will receive payback after the third release.
In 2013 Jeff Atwood added:
Component culture is a phenomenon linked to the obsession with perceived and anticipated reuse and productivity regardless of the downstream effects much like the past obsession with class-orientation (where criticism started mounting back in 2014).
Mass production in software is a solved problem; you want another copy of a program—you just copy it. You need something a little bit different—then you have to “mod” it.
The Elm community observed that “components” don't work for them. They always ended up with a Model-View-Update triplet, i.e. three related but distinct compositional units.
Any attempt to encapsulate these three inside a unifying component wrapper always resulted in unacceptable downsides in terms of maintenance and runtime behaviour.
More universally, inappropriate (component) boundaries will always impose an unnecessary cost, as they are the wrong abstraction (talk).
And as Chad Fowler (“Professional Systems Euthanizer”) observed back in 2014(, 2016 and 2017):
Impermanence: the ironic key to systems that survive—disposable components
i.e. boundaries dictated by areas of high rate of change are preferable to those implied by potential areas of reuse.
Replace-ability > Reuse
The other issue is that almost nobody wants to build Web Components from scratch. Lit is positioning itself to be the “blessed” framework for building Web Components.
But there are countless ways of building Web Components so each independently sourced WC has the potential of dragging in yet another WC framework/library, using a completely different integration style (attributes/props, or custom events).
Not something you should subject your visitors to.
In the web space tools and approaches become “popular” because they are convenient, not because they represent excellence. To achieve excellence it's often necessary to do what is inconvenient.
I'm impressed how, in your 372 words of an answer, I've found exactly zero valid points that could tip the balance in a way or the other. In other words, I absolutely have no idea of what you were trying to say, especially in relation to my answer.
The main driver of your motivation is reuse.
That is a problematic motivation when it comes to software design and implementation, largely because it requires clairvoyance on the part of the designer/developer (unless it's already been done several times before, i.e. experience); relevant reuse is mostly discovered, not designed up front.
So it makes perfect sense to first design a component in React, then in Angular if need be. Once you also have to create one for Vue it may make sense to try to extract one common implementation, one that works equally well in all three cases (though often the result is just equally awkward in all three).
A more optimal solution may be extracting some framework agnostic logic that can be shared among all three but doesn't fit the definition of a convenient “component”.
And the notion of “doing the right thing the first time” doesn't wash in most cases because most knowledge only exists once you are done. It's only once you've built the React, Angular, and Vue version that you have a much clearer picture of what can be effectively and efficiently shared.
One important criticism to React is:
“… that's like React's biggest simplification, its biggest flaw—they are basically equating your data tree with your view tree …”
This can apply equally to WCs where what is ostensibly a DOM element takes on application responsibilities while having to somehow interact with the rest of the application in some bespoke manner.
The thinking behind WCs is rooted in 2010-era thinking of object reuse and client side rendering and ultimately limited by it.
Declarative Shadow DOM is just the latest layer of complexity introduced to the WC standard (and by extension browsers) in an attempt to address the shortcomings locked-in by the assumptions made back in that climate.
And in terms of solution architecture starting with hexagonal architecture (2005) the wisdom has been that a sound, maintainable solution should dictate the interfaces it depends on (narrowing API or pattern of usage API), rather than accepting the interfaces already exposed by the dependencies.
So anything reusable may incur the overhead of a DMZ or anti-corruption layer.
This is all purely academic and scarcely applies to reality; and it's also jarringly distant by the concepts we've been talking about. OOP isn't even a discussed issue here.
You end up justifying rewriting components because "third time's the charm". From a business point of view, this is suicidal. Are you going to pay for that?
Also, some statements are factually wrong. Web Components have always been a "work in progress" so far. The issue of server side rendering has been known since the inception: HTML Imports would have been the solution, but then different paths have been taken so far.
Components are an embodiment of OO. Always have been, always will be. Perhaps this is a “can't see the forest for the trees” situation. Also: Document Object Model.
That's a commonly held belief. That's why I brought up Chad Fowler. By adopting a “so small, it's trivial to rewrite” approach eventually at Wunderlist they got to a point where they could continually change without having to wait for the next “big rewrite”.
Now if you have hundreds of components, supporting yet another framework can sting but if everything is “trivial to rewrite“ maybe its doable, especially if there are numerous areas that are independent enough to be built concurrently.
Now the Porsche Design System v3 seems to be largely WC based but explicit support of React/Angular/Next JS/Remix/Vue will still result in the “write once, test everywhere” syndrome.
They aspire to be “components” mounted to the DOM. The boundary implied by that is locked-in. Customizing built-in elements is one thing, components are a different animal altogether.
They could be functions, they could be numbers, they could be Easter bunnies. Nobody cares. It's academic trivia.
I.e.: absolutely nobody.
"No rewrite" is always less work than "trivial to rewrite".
This is historically inaccurate. The conception of Web Components predates React, and the time when Angular JS started calling them like that. Nowadays, the term has been tainted by the success of React et al. and it's widely recognized that it doesn't fit the definition of Web Components. But Web Components have never changed their nature.
If different versions of a framework can't co-exist Web Components isn't changing that when it comes to authoring them in said framework.
I'd understand how I might have this perspective if I hadn't spent to time to do both Web Component wrappers in frameworks and attempting framework in framework without them. Both require decent amount of work. On one hand the framework maintainers takes the brunt of it when it is with webcomponents because they build towards a standard, but on the other hand the hoops you need to jump through are more limiting than if you just put one framework in another.
A perfect example of this is something like Context APIs which serve as an internal mechanism to provide shared state. You can do similar APIs with Web Components (I was involved in early discussions in WC Community group on this topic). But making a frameworks Context API work across WCs is actually a bigger pain.
Timing becomes an awkward consideration and Context needs to exist and persist beyond DOM elements. Now I've worked with different tools to figure out how to create patterns around this. These frameworks generally aren't designed to work in isolation. They get incredible benefit from coordination. It is actually easier at times to have the frameworks have an interface between that suits each of them rather than try to force a standard interface that impedes.
So on one hand they could never accept a WC only mechanism because their needs transcend them but on the other hand WCs actually get in the way.
Back to the beginning. You can't use a React Component in Angular app. You probably could. Kind of like how you use a Web Component in an Angular app. But you are doing both frameworks a disservice unless we are talking that one off type case. You limit their ability to be the best versions of themselves.
I say this knowing this fact alone would get in the way of the adoption of my own framework. But how could I ever recommend a path that didn't give people the best chance to build the best possible sites and apps.
This may not have been intended to be taken broadly (e.g. may be specific to mixing frameworks or overhead of just using WC instead of a particular framework, etc).
So, with that out of the way, I'll just list a few major use cases for WC which have proven to be very beneficial for my small team at eBay. 1.) Enhancing existing legacy websites which are non-JS on the server-side and 2.) Code sharing across completely separate platforms and vendors. The simplicity and composability of defining a tag with a simple API to define the tags state (i.e. it's attributes and contents/slots) interfaces quite naturally with server-rendered languages like PHP. You can also leverage it to share code in situations where you can neatly package up your UI component for use on third party vendor sites (like those which, ahem... wrap their entire page in a giant
<form>
tag...) so that your own site search<form>
doesn't break everything. 😅Much of what you said is still true with respect to some of the introduced complexity! Some of the tradeoffs however make it still worth it, especially if it is carefully architected.
Did microfrontends ever come in full-swing at eBay? I remember giving a talk about them there where the Marko team had come up with a mechanism to do server microfrontends in an attempt to improve performance and convince people that Module Federation was a terrible idea.
Web Components are sort of the same. I think people probably have a real need for something in this category. There is too many organizational(people) coordination concerns that get in the way of being able to do the best possible thing. This is what I mean when I talk about "mixing" not being ever where you want to be. Obviously it is a place you are forced to be. I just don't think we should welcome it. We should like with microfrontends try to find any solution that works until we absolutely need it.
Web Components can be a great tool that we could get excited about when it solves are organizational problems. But it should not be a solution we should be excited about to solve our technical problems.
Yeah, while I don't write any Marko code, I think this is it: github.com/marko-js/micro-frame. I remember attending a talk internally about it.
Understood(organizational vs. technical). Two completely different and difficult issues, particularly in larger organizations, to be sure! I'd add "legacy" as another technical challenge here as well. Legacy salted with a bit of "not a lot of time" (b/c otherwise you can technically solve it by scrapping and rewriting). I think pure frameworks offer a better overall technical approach, particularly when you can roll everything together. You end up with overall far better and more cohesive solutions. My current heavy use of WC's is in the realm of using them as a portal for a sort of middleware to help glue things together; it is part of the technical solution in the "real world" of multiple competing challenges (yes, particularly organizational and of course legacy).
This is a reality for some businesses, @ryansolid - especially for SMBs in the enterprise sector. Not everything is a greenfield startup and OP correctly points to SAP, Salesforce, and friends. I have multiple clients who serve a niche industry in those ecosystems where components are used in all kinds of custom development projects and are made available as a library to their customers if they want to do the implementation themselves. I work with those clients to get their UI library from React-only to Web Components - exactly because they cannot reimplement their incredibly specific stuff over and over again.
A lot of React code has been written in the enterprise world - and it doesn't seem to slow down. The cost you're describing is basically one way to open the door for other frameworks, like Solid, Svelte, or Vue. That's the benefit: allow enterprise to be something other than React. As OP pointed out, libraries like SAP UI5 are an example of that: "Here's how the world looks and behaves according to SAP, now use it in any framework you like".
It's ok for a framework not to care about Web Components, but then at least my little corner of the enterprise development world won't care about this framework either. My clients would rather use React until the end of days before rewriting their stuff again - because similar to what you say about Web Components, the cost of rewriting stuff in a new framework is regrettable over a benefit that is mostly superficial.
End note: I only speak for my corner of the enterprise world, I'm sure other corners have a different view. I also use Solid on a greenfield project with another client - and it's amazing. Love your work!
Precisely. I think we can all actually agree that there is indeed a cost there, particularly in that compatibility layer or in the tooling in order to glue things together.
In fact, I use WC as a portal/API to implement components my way (which just happens to be Svelte in my case). I can still use slots and I have some basic component lifecycle stuff that I hook into. Then you can roll what I built wherever WC's are supported.
Regarding using slots in the light DOM: My library
svelte-retag
integrates Svelte slots using web components in the light DOM (with some support in shadow DOM as well). It's very composable and even supports Svelte's context as well.That said: I will say that using slots in the light DOM isn't anywhere near as robust as native shadow DOM slots. Without diving too much into detail, one example is how things "just work" when you manipulate slot contents and those contents are reflected as you might expect in the host element, whereas doing that in a light DOM implementation may not always work as expected (or even be feasible in some scenarios). This is because modifications to slot contents after mount could cause unexpected results. So, in that sense, the isolation that the shadow DOM brings is very much a feature when working in a more native (i.e. framework agnostic) context.
Now replace "Web Components" with "Microservices".
Please take this as just another perspective, not an attempt of arguing that yours is less valid, but while reading this post I've found myself repeatedly just thinking "what are they even talking about?"
"web components" are definitely trying to be a somewhat generic API that doesn't lock people into one very specific paradigm; they're designed to be more of an in-between layer serving as a transpilation target or lower-level API for more high-level component systems.
But they're still not a catch-all system for building "components" in the broadest sense. Maybe the name web components was somewhat poorly chosen in that regard; colloquial names for web technologies have a habit of doing that (looking at you, CSS variables 👀).
The API that sits at their centre, "Custom Elements" is probably a much better name if you want to be specific. That's the use-case they're trying to cover. When whatever you're trying to build fits neatly into the concept of a single independent HTML element, but none of the built-in ones have you covered, then you can simply build your own using a custom element; and once you've done that, you can even share it for other people to use them.
"Components" are really a much broader concept, that's very loosely defined. It's somewhat more granular than a "view" but generally more complex than an element. Are rails partials "components"? Hard to say, specially if they have inline javascript.
There's also no rule that components need to be limited to a single top-level element; maybe some implementations impose limitations like this, but that's an aspect of those systems, not of components as a concept. Some browser APIs even allow for this:
<template>
elements can have many child nodes that simply get inserted next to each other. Remember: "web components" is an umbrella term for the combination of several features,<template>
s being one of those as well.I've been using and misusing custom elements for lots of things myself, and what I can say is this:
The design is clearly centred around simple, re-usable and generic custom elements of similar or just slightly larger scope than most built-in elements.
They can be used for larger scope stuff, like user cards, calculator components, etc. but they clearly weren't built with that in mind. Therefore there will also be a lot more friction when trying to use them for these situations. You can, and they certainly do work for that, but that's not their exact intended purpose, and it shows.
So it feels a bit weird to hear criticism of web components based on this; your post reads a bit like a complaint that a sushi knife struggles to cut through freshly baked bread.
Maybe I misunderstand your criticism, and am just missing how it also applies to smaller components, but the way I understand it, the real problem isn't web components, but the lack of a built-in mechanism for larger scope compositions. Personally, I'm not quite convinced that browsers should even provide those; frameworks are probably way better at implementing something like that.
Wait a minute...
So because Web Components are a standard, I have to use them?
What's next? I have to use
proxies
andgenerator functions
in my applications?I totally disagree with your post. With hindsight I shouldn't have read it.
Sounds to me you are a disgruntled "My-Web-Component-wrapper-is-better" creator who sees Web Awesome coming at the horizon. And sees all his efforts wasted.
And no, I have no stock in Web Awesome; been doing standard JavaScript Web Components for the past 7 years, without any 3rd part s*, almost full-time.
You don't have use them, but generic tools now have to account for the edge case that come from them. How things like event delegation are handled, or async upgrade of webcomponents, or how attribute/properties need to be considered for elements that define their own interface. Or how their timing works different when cloned between cloneNode and importNode. Or a million other little details.
You don't have to use them but any tool now has to consider them if they want to support the whole web platform which means extra complexity, code, and runtime overhead for everyone.
Not to mention how their very existence influences how newer features are approached. They now need to work with Custom Elements and the other web component specs.
The cost of decisions that extend the capabilities of a platform go beyond isolation of a single feature or featureset. That's the thing more people should recognize.
Its called standards.
Web Components is not about technology, but about 4 major companies working together.
But I will happily transport you back 20 years in time when we had to develop for 4 different Browsers.
No I was there. I don't want to go back. I don't have an issue with Standards in general. But there are reasons, as a technologist, Web Components in particular stand out. I empathize with the challenges then and now to get here. I remember some of what I thought were outrageous asks from Apple regarding the shadow dom, the dance around native element extensions, and V0 vs V1. Getting everyone coming together is a feat in itself.
Ryosuke Niwa recently thanked the WHATWG community for their efforts.
You know that community, so you can value what that sole remark means.
That standards body is the only body that will decide what runs in the browser for the next 25 years.
Fight/ignore them or join them, those are the only options you have.
And in joining you can chose to follow every Web Component fart Google releases;
join the community sessions: github.com/w3c/webcomponents-cg/is... and validate your arguments are valid,
or only focus on technologies supported by all 3 Browser engines.
I have been doing the latter for the past years, does it feel as exciting as my tour of Internet-duty in the 90s...
No, but I know this old geezers code will run without any issues for the next 25 years
I stopped using Frameworks when Google called Angular 2 an "upgrade", so never had the urge to create a I-can-do-Web-Components-better wrapper.
Will the WWW be around for another 25 years... maybe not... there will always be smarter people, with smarter marketing (technology doesn't count) I looked in the mirror years ago and concluded I am not good (enough) at marketing.
Fighting evolving standards... been there... lost when WWW trumped my early 90s Gopher dabblings.
Yes, it will hurt to let Solid go...
From the looks of it, you're the disgruntled one
O yes, I am,
For the past years I have mainly read complaints from people who then create _A-better-Web-Components-wrapper
Stopped counting at 50+: webcomponents.dev/blog/all-the-way...
And now they blame the technology for their mistake??
Ryan his post is about his mistake to write a wrapper around Web Components technology.
Nothing new, happened in the MooTools/ExtJS/Zepto years too. When jQuery became de defacto standard, many coding hours using the "wrong" tool had to be dumped in the bin.
We will see a lot more of these posts in the coming year, 50+ authors can delete their GitHub repo
I've written 4 sites in uncompiled LitHTML and it's a relief:
How does Dependency Injection work?
Great post
Frameworks are indeed abstracting web technologies away, and that is a good things.
We don't program in Byte Code or in Assembly code, because that is not the level of abstraction we want to deal with. Could we build a website in Assembly? Sure, but we don't want to.
We build websites with Frameworks. But we build also native apps, and VR apps, and terminal apps with Frameworks. Or even Windows Start Buttons. Just like my Assembly code can run on different processors, the work in my Framework can run in different digital experience platform . The framework should decide how it works with the primitives of that platform (browser, vr environment, native app, etc.) and the platform should stay as unassuming as possible.
It feels to me that this article compares frameworks and web components like comparing a monkey and a fish and saying that the monkey doesn't have a future because it would lose in a swimming contest.
A lot of the components you speak of, or those "micro-frontend" bits, are often pieces of logic, a way to organize frontend code, "functions" in a way. For that reason, they're very JS-oriented, and they align well with SSR and build tools, and they need abstractions like fine-grained reactivity (swimming).
This is all good, and indeed not the sweet spot of web components. "Widgets" like ZenDesk is indeed a better example, but also more importantly a set of UI components (design system) rather than app components. A button or a calendar doesn't need microfrontends, doesn't need "fine-grained reactivity", and might not need a full-fledged full-stack framework that isomorphically converts JSON to HTML to render. It needs good encapsulation around styles and DOM (e.g. namespace), be portable and somewhat detached from how the organization builds "apps" or "frontends".
Web components still have ways to go, and I don't know what the future is... Perhaps ever-evolving frameworks would continue to be the future of frontend development and web components will be, well, a component in how people integrate widgets and design systems?
I think your own article highlights how to construct a web UI in a composable manner without necessarily resorting to “components”.
Yea, I think components are an overused idiom for frontend, but I agree with the author that they could be a useful server/build-time construct.
But where components, and web components specifically, are really useful is in reusable component libraries (your buttons and calendars) and widgets (your ZenDesk).
If this isn't hyberbole, I don't know what is:
"It's the promise that they are something that they aren't which is so dangerous. The way their existence warps everything around them that puts the whole web at risk. It's a price everyone has to pay."
Maybe try to support your argument with data instead of hyperbole. I'm skeptical a library can produce components more performant than custom elements. With no data to back up your claim, I'll remain skeptical.
I think the main issue is that Web Components were standardised according to the prevailing paradigms 10 years ago and Frontend development has moved past those ideas. Then, Web Components couldn't live up to the expectations people had they would fulfil. Now, they are widely supported, but things like Shadow DOM complicate development rather than being helpful, if you don't need that strong encapsulation. Also, back then, most frameworks embraced client-side rendering as the way to go. This was clearly a mistake, but frameworks pioneered this approach, Web Components followed, and frameworks moved away again in the last decade. Web Components stayed there, at least in the mental model of developers and framework authors. Those mental models are the cost Web Components impose on the community.
But that aside, one can definitely use Web Components in a beneficial way. Just don't use Shadow DOM if multiple components come from the same trusted source and should have little barriers for sharing styles. Custom Element tag names with light DOM are a great way to have unique block scopes for styles.
Server-side rendering of Web Components is possible with any backend technology. Just render HTML and bundle assets as we used to do 20 years ago. No JS framework has such minimal requirements and such an easy interoperability with all sorts of backend technologies. Nobody forces us to do client-side rendering.
Web Components don't have a state management solution. But it's possible to build one that converts observed attributes to signals, sets them on user interaction and does only the necessary fine-grained updates in the DOM with effects. It takes about 1 to 2 kB of gzipped library code to do so. You simply can't have such a minimal footprint AND the full power of reactive frameworks with a full-blown JS framework that implement all the features Web Components already provide in JavaScript again.
Great article
Please also write an article about WebForms Core technology. WebForms Core is a technology where HTML tags are managed from the server.
WebForms Core article:
dev.to/elanatframework/using-webfo...
Video of how WebForms Core works:
youtube.com/watch?v=zl4sxjIkBwU
You chose to solve problems with your own solution, even though there was an option to improve the existing Web Components in the platform. You're simply experiencing the consequences of that choice. If you want to reduce the price you're paying, contribute to improving WC.
I did go the fully embracing web components direction. It just isn't the right abstraction. Asking Web Components to change to meet the needs of modern frameworks is sort of pointless because it would require fundamentally changing what they are.
Thank you for your reply. I have carefully reviewed both your previous article about Web Components and the current one. So, is my understanding correct that what you’re saying is that the outdated assumptions underlying Web Components could become a headache for the future development of the Web?
Funny how somehow Web Components and Blockchain tech give me the same kind of "vibe" - both feel like "solutions in search of a problem" ;-)
Great article. Web Components are a hype and unrealistic expectations, maybe they are useful in some scenarios, but when I tried them they seemed like a mess.
There are no silver bullets in coding, but some people insist there are.
Shared article and following you.
I found this post very sad and unconvincing. It baffles me that someone would argue so forcefully against browsers evolving in a way that gives us more powerful tools as developers. There are soo many things we can only do if browsers allow us, and having lived through the decades where browser innovation was stifled (IE 6 anyone?) I would never go back. Of course these standards are imperfect, but to argue so vehemently against their existence is quite discouraging.
I think it's great that library authors have the option to distribute their code in a form that can be used with any of the popular UI frameworks. The SSR/SSG issue is currently the biggest drawback, but declarative Shadow DOM will fix that eventually.
Declarative Shadow DOM has already fixed that. 🤷♂️
caniuse.com/declarative-shadow-dom
I can clearly see how this is deeply inspired by your own experience with your framework. It's inspiring to read, and I can appreciate the progression of ideas you’ve become aware of throughout your journey. What stands out to me is the notion that, even when dealing with abstract ideas like finding a universal concept to replace web components—something that remains plug-and-play over time, regardless of future standards, technologies, or frameworks—you still manage to ground it in technical details such as the DOM, properties, and attributes.
Overall, the article conveys how experience naturally drives changes in our implementations. We’ve learned that concepts like coupling and abstraction are things to eliminate from our designs. Personally, I would like to see the removal of the dependence on the DOM for whatever concept we develop next, if that's a reasonable compromise. However, as many commenters have pointed out, is this even a problem we truly need to solve?
I’m inclined to follow your thinking when you say, ‘The glue is always what takes time.’ But is there really a way to 'glue' something when we can't predict what it will look like, given how many variables are at play in our evolving development ecosystem? It makes me think of TypeScript and how its definitions can auto-adjust, but even then, TypeScript binds us to a certain contract.
A second good example of a web component is the Mux Video Player. I agree that 90% of the time, the complexity of a Web component is not worth it when considering integrating it into a production application and team.
To me, the most important takeaway from this article is that Web Components tried to be the solution to a problem that was still being defined. It could have been everything it promised, but it was set in stone before the problems it tried to solve were even defined.
As a final point, try to find a clear post about building and publishing a web component with something as common as Tailwinds in a framework like Vue that is supposed to be supported at the framework level. There isn't.
You're overlooking a key point: many frameworks force you to use JavaScript on the server side when you need something efficient like Server-Side Rendering (SSR). Without SSR, you're bypassing the browser's parsing and rendering process in favor of client-side function calls, which results in a major performance hit. Even if you're not using SSR, you still need Node.js to develop with these frameworks, which can be annoying if you're working with a different server-side language.
With web components, I'm just writing HTML and client-side JavaScript (as god intended), and the browser handles the rest. I can use any server-side language or framework I want—or none at all. Thanks to Declarative Shadow DOM (DSD), I can perform SSR/SSG with any language. The trade-off is that I have to write more code, but it's a worthwhile exchange for my use case.
Web components were designed to extend HTML, and they do that exceptionally well—sorry if you don't see the value in that.
I have gone through a few frameworks, and every time I work on a framework, I have to spend a lot of time building a uikit, which is a boring job. And one day I approached web components, and I also had a uikit set for myself with all the necessary components. Now I no longer have to waste time on previous boring tasks, and I no longer depend on different frameworks. How wonderful.
pureui.xyz
Next year, surely!
I think the issue for me, is that you've viewed and presented web components, through a very specific lense. It's not what I'm building; or it doesn't compliment what I am building.
I View frameworks through a very specific lense, which I'll be too polite to exhastively convey here, and if pressed on by a person I might use words like "interesting", or "very clever". They are interesting. They are very clever.
I Think in general, most focus on solving edge cases, and are over-used by teams and contributors, who wouldn't intrinsically need a framework to solve any of their "real problems". And instead, the framework becomes the crutch of doing what we can, rather than what people need.
I Can see that typing and getting back the HTML in the correct order with event listeners, etc could be very useful. And the great news is that I can get that done, using a web-component.
Where that happens, seems like an interesting question.
What you need to build as-well-as that is also an interesting question.
How can I build something that solves for both of those... feels like a boring detail. A Footnote, some Errata.
It seems that the author has never worked really with web components. The author seems that he is only frameworks' users. We have been working on our in-house-built UI library already for 6 years, and we are happy with this and have integrated them into a huge enterprise system. We do not depend on any external dependencies in all these cool-child frameworks. From this year on, we integrated custom elements into Angular with SSR.
Sorry, I find this article incompetent; it is mostly emotional, and I haven't seen any real technical or business arguments.
PS. You can use web components even without shadow DOM; just use common DOM; it is also an option ;).
If you read the article you know that isn't true. I've been using Web Components for over a decade. I spent 7 years supporting a decent size app in production on web components. I introduced my company to them and did the migration back in 2013 until the software was retired in 2020. I've also been the author and maintainer of Web Component libraries, built and contributed to polyfills. I have a deep understanding of the specs and features and the experience working with them every day for many years.
I'm glad that web components worked for you. They worked for us too. But that also doesn't satisfy as a technical argument. I could bury you in technical arguments but I chose to summarize them as the actual implications are much wider. As I stated in the article the Shadow DOM while problematic isn't the only problem, component lifecycles, tension with attributes/properties, SSR, performance, and most importantly the consideration this impacts on future platform decisions are all things we should be looking at. People can definitely find success with them, but that doesn't mean they are arguably the least efficient way to solve the problem. And their impact in existing is definitely not free.
Hey Ryan, I'm just challenging myself to come to this conclusion after using it for my current HTMX freelance gig.
one more thought, I'm thinking of building web components based UI library using solidjs or sveltejs. solid-element primitives seems promising for
This reads more like a complaint than an article with substance. I wonder if the real reason behind it is that Web Components are making Solid redundant.
Also, your writing style needs some work—it feels more like an angry rant than a cohesive argument. No hard feelings, but it was really painful to get through and I don’t think I can get through another article of yours. 😉
This is an article about React, by a React developer, for React developers. As React devs do.
Wrong on all 3. It helps to read the article.
I don't disagree with your conclusion though.