Web Components Are Not the Future
Ryan Carniato

Ryan Carniato @ryansolid

About: Frontend performance enthusiast and Fine-Grained Reactivity super fan. Author of the SolidJS UI library and MarkoJS Core Team Member.

Location:
San Jose, California
Joined:
Jun 25, 2019

Web Components Are Not the Future

Publish Date: Sep 26 '24
425 121

A few years ago I wrote an article suggesting that Web Components might not be the most beneficial direction for Web development to head.

It was a soft-handed look at where they made sense and where things fall apart. It wasn't geared as a "us against them" argument and I hoped people would come to reasonable conclusions for themselves.

But over the past few years, I've only seen the situation worsen. Some may have never taken Web Components seriously, but I always have. I used them in production for 7 years. I wrote several polyfills in the early days for things like the Shadow DOM to use them before they hit prime time.

But my experience then and my experience since only points me to a single conclusion. Web Components possibly pose the biggest risk to the future of the web that I can see.


Visions of Utopia

Image description

I admit that statement comes off a bit heavy-handed. But many reasons lie below the surface as to why I believe this. And it starts with understanding the proposed benefit of Web Components.

The vision of Web Components is that one day regardless of what tool you use to author them you can have components that feel as native as DOM elements that can be added to any website without consideration of how the website is authored. No concerns about specific build tools, specific runtime mechanisms, or the way one would ever interface with these components would ever change.

In a sense, a portable interoperable web. One that can mitigate the future need for migration. One that sets you up for any possible future. The perfect way to future-proof your sites and applications.

A compelling prospect is it not? This is exactly why the promise of Web Components is so alluring and so dangerous.


Competing Standards

Image description

I didn't need to pull up the old xkcd comic for you to know the challenge with standards. The more ambitious the standard the more likely it will have opposition or alternative approaches to accomplish it. This doesn't go away when something is standardized. It just suggests that there is one blessed way. You can take it or leave it.

If the sheer number of JavaScript frameworks is any indicator we are nowhere near reaching a consensus on how one should author components on the web. And even if we were a bit closer today we were nowhere near there a decade ago.

The introduction of higher-level primitives can have a positive effect. Suddenly something harder to do becomes easier. Which initially leads to more exploration. Web Components caused an increase in the number of JavaScript frameworks in the mid 2010s. It was an important inspiration for why I created SolidJS. A similar example would be the increase in Metaframeworks being built thanks to Vite.

But it also can have a negative effect. If too many assumptions are made it becomes harder to explore alternative space because everything gravitates around the establishment. What is more established than a web standard that can never change?

I've struggled with this a ton outside of web standards. JSX according to the spec has no established semantics but try to convince the wide range of tooling out there they are assuming too much. I can only imagine the nightmare it would have been if JSX had been standardized in the browser. Forgetting how frameworks like Inferno, Solid, and Million, have done way more optimal things with their JSX transform, even React has changed their transform over time.

This is but one example of many. Things that help us, can effectively tie our hands. We must tread carefully when standardizing any higher-level mechanism because it assumes a lot. It is insufficient to say not everyone has to use it when its existence influences how we look at the platform in general.


Opportunity Cost is Real

As a framework author, I understand this too well. I often say that in this field things are discovered as much as they are invented. What I mean by that is there is a certain truth/physics, if you will, to design decisions that when followed lead us all to similar places. It isn't that these tools copy each other blatantly. They fall into the grooves.

And for the same reason once a discovery is made that changes our outlook, the damage is done before we write a single line of code. If your job is to design a system you don't want redundant parts. You want clear purposeful boundaries. Instead of making a million variations on the same thing you try to re-use one thing. More so recognizing that to accomplish common tasks you need multiple things these pieces become intertwined.

For example, React developers definitely felt how long it was between the announcement of Suspense in 2017 and when we finally got a data-fetching story for RSCs in 2022. Why did this take 5 years? Because it wasn't a straight line. It took a while to understand how all the pieces fit. That in itself is reasonable. But more, React didn't want to release it piecewise until they knew they had an answer for the whole story. As they looked more and more, all these pieces were related and while they could be broken up they needed each other to paint the picture.

RSCs do not fit everyone's idea of how data fetching with Suspense should work in React. Maybe people could have benefited from a client data-fetching primitive. React chose to be ambitious here which is their right as a tool and decided what was best, but this could have played out a number of ways.

As a developer, I can always choose not to use React. And while I can choose not to use certain React features it is clear everything in React has shifted to their current mental model. I might even be wishing I could easily migrate off React.

But there is a big difference here. React is a library and it isn't a Standard. Those options aren't the same when it comes to Standards. If all I wanted was scoped styles and now I have to deal with the Shadow DOM because that was the abstraction that best fit with having a single way to do things due to Web Components, well that is what I'm stuck with.

When primitives overstep their desired usage, when they over abstract, you don't get to come back from that. You've already paid the cost. And as anyone who has done major architectural refactoring of a project can attest, the hardest part is adjusting boundaries. If things fall under the same logical grouping they are easier to update. It's when you need to break things apart that it gets truly challenging. You can always add another layer of abstraction to solve a problem but removing one can be difficult.


The Cost of Abstraction

Image description

So the fundamental problem with Web Components is that they are built on Custom Elements. Elements !== Components. More specifically, Elements are a subset of Components. One could argue that every Element could be a Component but not all Components are Elements.

So what? It means that every interface needs to go through the DOM. Some in well-defined ways that aren't a perfect fit, and some in newly defined ways that augment or change how one would deal with Elements to accommodate extended functionality.

To begin, DOM elements have attributes and properties. This is so that they can be represented as HTML. Attributes accept only strings while properties being a JS interface can handle any value. Native DOM elements have many rules around specific attributes/properties like how some are boolean (existence means they apply) while others are psuedo-boolean (needs an explicit "true"/"false"). Some properties reflect to attributes and others do not.

A goal of templating languages is to solve this in a uniform way. We can make special rules around known elements and attributes. But with custom elements we don't know. So this is why some templating libraries have interesting prefixes to indicate how things should be set. Even Solid's JSX we have attr:, prop: and bool: prefixes for this reason. Now every runtime location and compiler hook needs to be aware of this.

You might be thinking we need better templating as a Standard. But like JSX above you need to consider the implications of that decision. A few years ago most people would have probably agreed that the way something like LitHTML did template rendering was something was a good approach. Other solutions could output it. However, in the interim, we realized that reactive rendering, like what Solid does, outperforms it. It does so by changing the semantics of the templating. If we had moved ahead we would have a standard that would not be the best way to do templating.

It doesn't end there. DOM elements can be cloned. But Custom Elements have different behavior which means they should be imported instead. They have DOM-based lifecycles that can trigger synchronously or asynchronously depending on when they upgrade. This wreaks havoc on things like Reactivity tracking and Context APIs. However, these details are important to interface with native DOM behaviors and events. These are also all things that a JavaScript Component doesn't worry about.

There are other idiosyncrasies like the way event targeting works in the Shadow DOM. Some events don't "compose" ie don't bubble beyond Shadow DOM boundaries. Some events don't bubble consistently because they don't recognize a different target, like in "focusin", because the Shadow Host is always made the target no matter which child element gains focus. We could talk about these for days but I don't want to divert to much attention here. Some things are today's shortcomings and some are by design. But the commonality here is they all require specific consideration that otherwise wouldn't be necessary.

And of course this has a performance overhead:

But even if you consider this performance cost minimal, where does it leave us when going to the server for things like SSR? Yes, you can completely do SSR with Web Components. Hydration is completely achievable. But they are a DOM interface in a place with no DOM. You can make a minimal wrapper to handle most things but this is all extra overhead. All because we tried to make Components something they aren't.

On the server there is no such standard. We are back to having specific solutions. It is just another type of framework with no more guarantees than if I chose Vue or React for my next project. There is nothing wrong with that, but we need to recognize that fact.


The Real Cost of Web Components

The complete picture is one where the complexity of dealing with native elements increases to account for the new found flexibility of web components. It is something that as tools support them better, not only is the user of them paying the price of but all users of that tool. More code to ship and more code to execute to check these edge cases. It's a hidden tax that impacts everyone.

I've talked about where early standardization would have been catastrophic. But it also has the potential to stifle future innovation along certain paths because it assumes too much. Improvements to hydration, things like Resumability, Partial or Selective Hydration depend on event delegation to work. But if Shadow DOM messes with that then how could Web Components fit that model? SSR some might say was an oversight because we didn't think about that much in 2013, but this gap only continues to grow over time.

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. Something you have at authoring time that vanish from the final output. For optimal user experience we optimize away the components.

I'm not saying someone couldn't find some interesting solutions to these problems but they all imply taking on the hidden cost due to the foundational misalignment of having the wrong abstraction. This is what makes the dialog here so difficult. It isn't something you improve. It's just a mistake for a number of things.

Now we can all say different solutions have different tradeoffs. And maybe something like Web Components could only possibly succeed with support of things like Standards bodies because of how pervasive it would need to be to work. It's an ideal we are working towards and just aren't quite there yet.

But is it actually ideal?


Utopia Revisited

Image description

We often hit a similar debate when talking about Micro-frontends or Microservices. It is beneficial for organizational purposes to align projects with your developers. It follows Conway's Law.

The isolation or portability afforded by Web Components means that one could have multiple different components on the page from different sources. Now like the others prudence is in order. Similar to not wanting to write all your Microservices in different languages you might not want to author all your components in different frameworks.

But frontend is a much more restrictive space. The cost of each kilobyte of JS is not insignificant. It isn't only maintenance why you wouldn't want to mix and match but to reduce payload. And this is where the wheels start coming off.

If your goal is to future-proof then you need to be prepared to keep different versions of even the same library on the same page. This is no different for Lit as it is for React. You could choose to never update anything, but that is an option without Web Components too. There are no additional guarantees here. To future-proof the only the choice to freeze things, maintain multiple versions, and load more JS on your page.

Realistically you will update your libraries in lockstep which is also the same with any library. And in those cases if you only have a single library on your page Web Components aren't doing anything for you but adding more overhead. Possibly getting in the way of features that the library provides now and in the future. You might as well use the library without the Web Components.

The second consideration is granularity. If you have a Microfrontend then that is a contained swappable piece. If in the future you decide it isn't the best way to handle things you swap it out. But once you adopt web components everywhere you will need to address each of these touchpoints. Web Components differ from MicroFrontends and Microservices because they can be used cross-sectionally. This is good for standardization, but I've never seen a company that uses jQuery ever completely be able to get rid of it.

The most compelling uses for Web Components are as a sort of Microfrontend container. In that case, you don't pay the scaling costs, the outside communication is minimal, and they are easy to swap in/out. The one-off scenario. In those cases though the friction is low enough that having Web Components isn't necessary. I'd take them for the ergonomics to put a Zendesk widget on my page, but is the abstraction worth the cost?


Conclusion

And that is what it comes down to. I could not argue that there are not ergonomic benefits to using Web Components in some scenarios. But the cost it imposes everywhere is steep. While I shouldn't be quick to disavow a technology for the types of poor patterns it enables one to do, it is difficult to stand behind it when it never fits in the ideal scenario. At best it is a nominal overhead.

Web Components are a compromise through and through. As we know sometimes we need compromises. But that is nothing to get excited about. And some compromises are better than others.

It was presented to me that in 10 years from now it's possible no one would be using Solid but a Web Component would still be there with the same interface as today. But I thought for a moment and responded I'd still build it with Solid because that would be the best choice for today. In 10 years even if I had to use a 10-year-old version of Solid it would be better than the Web Component version. 10 years doesn't erase that. And hopefully in 10 years I'd be using something better.

The decision is completely orthogonal. So in a sense there are nothing wrong with Web Components as they are only able to be what they are. 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.

Comments 121 total

  • Bntstr
    BntstrSep 26, 2024

    Great post

  • ianstigator
    ianstigatorSep 26, 2024

    Now replace "Web Components" with "Microservices".

  • Matti Bar-Zeev
    Matti Bar-ZeevSep 26, 2024

    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.

    • peerreynders
      peerreyndersSep 27, 2024

      “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.

    • Dev Agrawal
      Dev AgrawalSep 27, 2024

      Web standards which are closing the gap and offer native solutions to challenges framework came to solve

      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?

      • Joe Pea
        Joe PeaSep 28, 2024

        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.

        • Ryan Carniato
          Ryan CarniatoSep 28, 2024

          Of course. I've been involved on a few of those discussions on the past. I want to quote this from my article.

          I'm not saying someone couldn't find some interesting solutions to these problems but they all imply taking on the hidden cost due to the foundational misalignment of having the wrong abstraction. This is what makes the dialog here so difficult. It isn't something you improve. It's just a mistake for a number of things.

          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.

          • Joe Pea
            Joe PeaSep 30, 2024

            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.

            • Joe Pea
              Joe PeaOct 1, 2024

              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.

    • Ryan Carniato
      Ryan CarniatoSep 27, 2024

      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.

    • Alex Lohr
      Alex LohrSep 27, 2024

      I think you're trying to make web components more than what they are

      He doesn't, but other people do, and that this can become a problem is the point of this whole article.

      The sentiment I get more and more is that frontend is in a complete mess because of frameworks

      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.

      Web standards which are closing the gap and offer native solutions to challenges framework came to solve.

      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.

    • 𒎏Wii 🏳️‍⚧️
      𒎏Wii 🏳️‍⚧️Sep 28, 2024

      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.

    • Daniel Macák
      Daniel MacákOct 9, 2024

      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.

      • Matti Bar-Zeev
        Matti Bar-ZeevOct 9, 2024

        "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.

        • Ryan Bower
          Ryan BowerOct 14, 2024

          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?

    • Kevinleary.net
      Kevinleary.netJan 10, 2025

      I largely agree with this, particularly the part about frameworks being created to fill gaps. We forget that was the original intention.

      I also think to some degree frameworks are created for the benefit of the organization creating them. Angular may make perfect sense for Google and a team of 100 engineers, but its overkill for many of the web apps I've seen. But yet, we vehemently support the "best practice". What's best is entirely subjective.

  • Benjamin Atkin
    Benjamin AtkinSep 27, 2024

    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...

    • Ryan Carniato
      Ryan CarniatoSep 27, 2024

      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.

      • Massimo Artizzu
        Massimo ArtizzuSep 27, 2024

        But is mixing multiple frameworks ever a place you want to be.

        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.

        • peerreynders
          peerreyndersSep 27, 2024

          “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:

          We think we've built software that is a general purpose solution to some set of problems, but we are almost always wrong. We have the delusion of reuse.

          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.

          The most amazing achievement of the computer software industry is its continuing cancellation of the steady and staggering gains made by the computer hardware industry.

          — Henry Petroski

          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.

          • Massimo Artizzu
            Massimo ArtizzuSep 27, 2024

            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.

            • peerreynders
              peerreyndersSep 27, 2024

              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.

              • Massimo Artizzu
                Massimo ArtizzuSep 27, 2024

                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.

                • peerreynders
                  peerreyndersSep 27, 2024

                  OOP isn't even a discussed issue here.

                  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.

                  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?

                  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.

                  Web Components have always been a "work in progress" so far.

                  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.

                  • Massimo Artizzu
                    Massimo ArtizzuSep 27, 2024

                    Components are an embodiment of OO. [...] Also: Document Object Model.

                    They could be functions, they could be numbers, they could be Easter bunnies. Nobody cares. It's academic trivia.

                    That's why I brought up Chad Fowler

                    I.e.: absolutely nobody.

                    if everything is “trivial to rewrite“ maybe its doable

                    "No rewrite" is always less work than "trivial to rewrite".

                    They aspire to be “components” mounted to the DOM

                    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.

            • Ryan Carniato
              Ryan CarniatoSep 27, 2024

              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.

      • Bob Massarczyk
        Bob MassarczykSep 29, 2024

        But is mixing multiple frameworks ever a place you want to be.

        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.

        I'm stating that they bring a cost to the platform that is regrettable over a benefit that is mostly superficial.

        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!

        • Patrick Nelson
          Patrick NelsonSep 30, 2024

          The cost you're describing is basically one way to open the door for other frameworks, like Solid, Svelte, or Vue.

          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.

      • Patrick Nelson
        Patrick NelsonSep 30, 2024

        over a benefit that is mostly superficial

        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.

        • Ryan Carniato
          Ryan CarniatoOct 8, 2024

          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.

          • Patrick Nelson
            Patrick NelsonOct 8, 2024

            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.

            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.

            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).

    • Patrick Nelson
      Patrick NelsonSep 30, 2024

      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.

  • Brian Kirkpatrick
    Brian KirkpatrickSep 27, 2024

    Next year, surely!

  • Jon Nyman
    Jon NymanSep 27, 2024

    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 add traits="x-modal" that would make it so once I add the dialog element to the page it would be treated as a modal without me actually having to call showModal() on the element.

    Or maybe something like <select multiple traits="fancy-select"> that would turn my select into a fancy select 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).

    • Ryan Carniato
      Ryan CarniatoSep 27, 2024

      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.

      • Jon Nyman
        Jon NymanSep 29, 2024

        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. With traits I could have multiple different enhancements on a singe element.

        Thank you for your reply!

  • Darko Bozhinovski
    Darko BozhinovskiSep 27, 2024

    The most compelling uses for Web Components are as a sort of Microfrontend container. In that case, you don't pay the scaling costs, the outside communication is minimal, and they are easy to swap in/out. The one-off scenario. In those cases though the friction is low enough that having Web Components isn't necessary. I'd take them for the ergonomics to put a Zendesk widget on my page, but is the abstraction worth the cost?

    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 :)

    • Ryan Carniato
      Ryan CarniatoSep 27, 2024

      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?

      • Darko Bozhinovski
        Darko BozhinovskiSep 29, 2024

        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):

        • Native FW components have some interop with the FW. It doesn't have to be perfect. It just has to be documented well, tradeoffs included. With examples, ideally. It shouldn't be the FW's burden to fix every API kink and type weirdness that a certain web component comes with. (This, for me, already works in Solid, but it lacks docs).
        • To address the complexity (and I imagine bundle price) - make it opt-in. Want web components support? Install/import that specific piece too.
        • You can compile native FW components down to web components. This is very biased, but it's because JSX feels like a better way to write components. It's not perfect, and it doesn't translate 1 to 1, but that might be good enough. (Solid already has this via solid-element).
        • More docs and more examples specific to this. Make it obvious to users and standard bodies etc. that this comes at a cost to the FW (which ultimately may cost extra in bundle size).

        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.

      • Bob Massarczyk
        Bob MassarczykSep 30, 2024

        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.

        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.

        • Ryan Carniato
          Ryan CarniatoApr 8, 2025

          A model that works beyond the web platform, on the server, on mobile, in the terminal. Considers places where the DOM doesn't exist and problems like hydration that do still exist in the web platform. One can claim it is of our own making but it isn't like the native solutions are solving this particularly well. Event delegation is a perfect example because it is the keystone of technology like Resumability or any sort of partial/selective hydration.

          The problem isn't that we created a model dramatically different than the web platform. It's that the web platform introduced a more specific (limiting) model in parallel to the work that was being done. And when I step back years later with today's context and hindsight while at one point I would have defended Web Components as raising the floor, I see now that too many assumptions were made. I know we all try our best, but sometimes we bet on the wrong abstraction, and we learn from it. Web Components are sort of stuck because now they are seen as a defining part of the platform. That was a choice and one that I think we will come to regret.

      • Nolan Lawson
        Nolan LawsonOct 1, 2024

        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.

    • Tomas Rimkus
      Tomas RimkusSep 29, 2024
      • "Universal cleaning solution is a solution which is good for nothing". No React, Svelte, Vue or Angular dev wants to use web components which integrate poorly with their framework. "Swiper" (swiperjs), for example, decided to ditch "Swiper Angular" components for web components in their latest version. Am I going to upgrade even the new version adds some nice features? Certainly not. Why? Because the new components have horrible DX compared to native Angular components and I don't want that ugly mess in my codebase.
      • You don't have to support every JS framework. You only have to support the ones which are actually popular. That's 3 frameworks: React, Vue and Angular. All 100 React derivatives can just use the React components.
      • The only case I know where WC worked to a limited degree is "Ionic" but even in that case they had to build their own wrapper on top of WC called "Stencil", there are quite a few workarounds to deal with WC edge cases, shadow dom makes it hard to style or query some dom elements when provided CSS vars are not enough, the React, Vue and Angular wrapper components are less than ideal as in some cases using them really does feel like you are using a wrapper and not a native component.
      • WC are not popular now and they will never be popular compared to dedicated frameworks. There might be some niche frameworks building on top of WC but most framework users will never choose WC over their preferred framework. Why am so sure about it? For js framework to be popular it has to have an eco-system built around it. No big UI component library sees it now as worth investing in and there are no signs that it will changing ever.
    • Ryan Bower
      Ryan BowerOct 10, 2024

      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.

      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.

      • Darko Bozhinovski
        Darko BozhinovskiOct 14, 2024

        While I get your point, you can still just attach an onClick and pass make the custom-nav-item just trigger navigate, 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.

        • Ryan Bower
          Ryan BowerOct 14, 2024

          The onClick approach is an issue for several reasons:

          • it passes the issue to the consumer, and it's bad dx for anyone trying to use the element.
          • it doesn't cover every use case. The link tag is a powerful element that gives you right-click context menu, open in new tab, etc. Now we're talking about lost functionality compared to the SPA link.
          • same issue with focus + shift-enter. We'd need to bind another event listener to check for keypress Now the dev has to account for default behavior that a typical <a> tag already covers for us.

          That said, I don't think I'd ever go for a custom nav item when using a framework.

          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.

          • Darko Bozhinovski
            Darko BozhinovskiOct 14, 2024

            Completely agreed. I have recently been dealing with evangelists that are extremely pro web components 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):

            1. Framework agnostic UI and design systems (especially a headache in huge orgs with different tech in different departments)
            2. Products that export UI-based SDKs for the web (and aim to support all frameworks).
            • Ryan Bower
              Ryan BowerOct 14, 2024

              Then, I don't think we disagree? :D

              Agreed haha.

  • Danny Engelman
    Danny EngelmanSep 27, 2024

    Wait a minute...

    So because Web Components are a standard, I have to use them?

    What's next? I have to use proxies and generator 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.

    • Levi Bassey
      Levi BasseySep 27, 2024

      From the looks of it, you're the disgruntled one

      • Danny Engelman
        Danny EngelmanSep 27, 2024

        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

    • Ryan Carniato
      Ryan CarniatoSep 27, 2024

      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.

      • Danny Engelman
        Danny EngelmanSep 28, 2024

        You don't have use them, but generic tools now have to account for the edge case that come from them.

        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.

        • Ryan Carniato
          Ryan CarniatoSep 28, 2024

          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.

          • Danny Engelman
            Danny EngelmanSep 28, 2024

            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:

            1. follow every Web Component fart Google releases;
            2. join the community sessions: github.com/w3c/webcomponents-cg/is... and validate your arguments are valid,
            3. 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...

            • Ryan Carniato
              Ryan CarniatoApr 8, 2025

              I mean if I could ignore it would be close to the right choice I think. The scope and problems that I've seen people wishing to solve in the WC community is both too ambitious and yet misses the mark to a degree that I honestly was hoping over time they'd just learn more and realize it. The problem is if you have to fight so hard to bring something to a standard and there is a real sunk cost to it, it is even more difficult to see the whole thing just get circumvented.

              The reality right now is the standards people are all over us to get basically Solid into the browser. I mean people can see how these advancements could benefit things. I'm actually sitting there being like, woah.. slowdown we're still learning stuff. The last thing I want is a repeat of Web Components.

              So this isn't setting some double standard. Some Animal Farm-ish change the people, same agenda. I legitimately think there is value in restricting way the base web platform elements can be extended. I think standards should be approached very carefully with the perspective we know nothing of the future.

              This isn't about a sense of attachment to my own work. It is about looking at the spectrum of known and potentially unknown solution space and like anyone else trying to make reasonable assumptions. It has nothing to do with marketting or business consideration for me. It doesn't sound like it does for you. This isn't about success. It's about what's best at the given time.

              And a given time is key. Because your old code, or the code I write today should run for 25 years as well. This isn't something that is unique to Web Components, but a principle of the web platform itself and why it is so important to be careful in how we introduce extensions to it.

              • Danny Engelman
                Danny EngelmanApr 9, 2025

                You, Rich, them React, Vue, Angular, Qwik guys; you are all brilliant in your own right.

                But neither of you are on the WHATWG playing field.

                Lead by example or stop whining

                • Ryan Carniato
                  Ryan CarniatoApr 10, 2025

                  Lead by Example? The fact that those tools exist is showing how things can be done.

                  Standards are tough. It takes a lot of wider consideration to be able to make decisions that impact basically everyone. Super hard on a platform like the web where you dont get to go.. oops we made a mistake. At least pubically. Angular can have Angular 2. HTML 5 or ES6 is not the same sort of next version.

                  But none of this means what is being said doesn't hold merit. Web Components can be the product of multiple brilliant minds and still be concerning.

                  • Danny Engelman
                    Danny EngelmanApr 10, 2025

                    I rode the Schiphol-Airport tunnel near Amsterdam for years on my Honda motorbike.
                    Always concerning "this is a potential place to die"

                    Last week I entered the highway, and kilometers before the tunnel my thoughts went: "this is a potential place to die"

                    And there and then I made up my mind. I can die anyplace on this motorbike.

                    Let Web Components happen, truly concerning technologies won't have a future.

                    It happened to the <blink> tag

  • Martin Baun
    Martin BaunSep 27, 2024

    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.

    • Stephen Belovarich
      Stephen BelovarichSep 28, 2024

      Declarative Shadow DOM has already fixed that. 🤷‍♂️
      caniuse.com/declarative-shadow-dom

      • Ryan Carniato
        Ryan CarniatoApr 8, 2025

        Does it fix needing to put the DOM on the server? It's a good output format but it isn't how you'd author your code. If your web components require JavaScript to run on the server.. tie into native lifecycles of the DOM you are going to need to shim and that is just another overhead.

  • leob
    leobSep 27, 2024

    Funny how somehow Web Components and Blockchain tech give me the same kind of "vibe" - both feel like "solutions in search of a problem" ;-)

  • Noam Rosenthal
    Noam RosenthalSep 27, 2024

    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?

    • peerreynders
      peerreyndersSep 27, 2024

      I think your own article highlights how to construct a web UI in a composable manner without necessarily resorting to “components”.

      • Noam Rosenthal
        Noam RosenthalSep 27, 2024

        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).

  • Elanat Framework
    Elanat FrameworkSep 27, 2024

    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

  • Esther Brunner
    Esther BrunnerSep 27, 2024

    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.

  • Kokomi
    KokomiSep 27, 2024

    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.

    • Ryan Carniato
      Ryan CarniatoSep 27, 2024

      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.

      • Kokomi
        KokomiSep 29, 2024

        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?

        • Ryan Carniato
          Ryan CarniatoApr 8, 2025

          Yes and that the way that they extend baseline functionality raises complexity for anyone trying to build on the web. Assumptions that could be made without their existence can no longer be made, and over time it feels like things just get messier and messier for that reason. It's like taking on someone else's technical debt while watching them continue piling more on.

  • Unlimited web tools
    Unlimited web toolsSep 27, 2024

    Interesting perspective! While opinions on web components vary, tools like Unlimited Web Tools can help developers streamline their workflow with features like minifiers and formatters, regardless of the technologies they use. Worth exploring!

  • 𒎏Wii 🏳️‍⚧️
    𒎏Wii 🏳️‍⚧️Sep 28, 2024

    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.

    • Ryan Carniato
      Ryan CarniatoApr 8, 2025

      I don't have any problems with WCs being less ambitious and leaving it to frameworks. The challenge is using an HTML Element as the container comes with a lot of side effects. Making it more difficult to make assumptions about how Elements behave. This applies to things like property/attribute handling. Like different casing for those and which ones reflect, values of strings vs other values.

      When the ability of elements is constrained we can build to them specifically. Sure there are weird special cases, so we special case them. We can treat them as the edge of our system. Almost like a serialization format. This makes web frameworks translate to cross platform quite nicely as we only need to abstract a DOM-like interface. And in some cases like Server rendering we can just forget about the DOM and rely on HTML strings.

      Now if we are just keeping to small VanillaJS written UI elements, that can represent all their behavior efficiently through string attributes, that don't leverage the Shadow DOM (that's a whole other can of issues), use lowercase event names(follow native event naming standards), and that only render in the browser. There isn't much trouble there. It's anything beyond that where things get messy.

      The thing is Web Component specs allow a lot more than this which means we can't make those assumptions. It isn't even like higher level mechanisms that are at play, but just the way that the features complicate the baseline that has far reaching implications.

      • 𒎏Wii 🏳️‍⚧️
        𒎏Wii 🏳️‍⚧️Apr 9, 2025

        The thing is Web Component specs allow a lot more than this which means we can't make those assumptions.

        Your point here seems to be that technologies should impose artificial restrictions to prevent usage outside of their intended scope, which just isn't a good idea in almost any context.

        Web components are a response to a specific need, and due to their generally very versatile API, they can also be used for a similar purpose on a much larger scale, but at the cost of some convenience because that wasn't their intended purpose.

        This really is a good thing though. It won't stop a new feature from being built to address the higher level composition needs you are talking about, but it will allow users to decide for themselves where to draw the line and use one over the other.

        The challenge is using an HTML Element as the container comes with a lot of side effects.

        It also comes with the very significant advantage that behaviour is encapsulated not only in JavaScript, but also in the HTML. Building a robust API without this 1:1 mapping of custom behaviour to DOM elements would likely be a nightmare for everyone involved, which is probably why there isn't a spec for it yet.

        • Ryan Carniato
          Ryan CarniatoApr 9, 2025

          These advantages only exist in the browser because JavaScript is still required. In so you can't rely on elements to be portable without their JavaScript. In a sense it is no different than any user defined behavior except you need to run this stuff through DOM interfaces now.

          It's funny but I do think we need to be very conscious of what we incidently allow through design. Frameworks might be working at a smaller scale than the web platform but it is a very similar exercise in looking at minimal interface packing the most power and consideration of how users will use the provided primitives.

          It's a bit like when someone asks for a feature or bug fix and it ends up breaking some usage you never predicted. Both the specific thing being asked for and the existing behavior are a result of some ambiguity at the edge of the common usage. These discoveries sometimes can be magical at times and often make it feel like everything is right when things fall consistently. But when things get too far from where they started you find yourself patching up hole after hole.

          What Im getting at is DOM elements are powerful in their own right without extending them this way. The consequences of these extensions break otherwise previously reasonable assumptions. Even if we accept that the end result isn't even in a zone that aligns with where things have been generally heading. I question the value of the use cases that they enable against the consequences of them existing. The problem is by their very nature I don't see this changing. It isn't a they just need to improve thing. It is more of we should have been less ambitious in the first place and more piecewise added any functionality deemed beneficial to the platform.

          • 𒎏Wii 🏳️‍⚧️
            𒎏Wii 🏳️‍⚧️Apr 9, 2025

            Custom elements aren't really that big of a deal. They really only provide one new feature: attaching code to elements without having to manually scan the DOM.

            The first half of this was already possible: MutationObserver and querySelector let you look for elements to be created or changed to match certain criteria for your code to start managing them. Custom elements just means the browser can do this in much more performant ways by hooking only into the parts that matter.

            This also doesn't really break any assumptions. Web Components are fundamentally incapable of doing anything that wasn't already possible; they simply provide a more specific API for it that browsers can more easily handle in performant ways.

            So no, there isn't really a case here, unless you want to argue that MutationObserver is also a problem for the same reasons.

            • Ryan Carniato
              Ryan CarniatoApr 10, 2025

              There is a difference between MutationObserver and Custom Elements. I often said the same thing myself.. we just wanted an onConnected event more or less and ended up with Web Components. I am not making this stuff up because I hit it being a framework author. We all do. Two areas come to mind off the top of my head. Attributes/Props and Asynchronous Element Updates/Lifecycles.

              Attributes/Props to be fair have always been able to be added custom there was just no expectation on behavior. Like differences between boolean properties and enumerated booleans.. We know draggable and readonly are different types of things but we don't know that about custom-enabled so we have to hold to some sort of convention when making templating languages. Also with more involved components there might be a desire to pass non-string values which is not a concern for built ins. Now obviously direct access to element or a prop syntax can help, but for things like SSR you are in a tricky place. There is a whole debate going on about explicit prop/attribute handling (like Lit/Solid) vs element inspection (Svelte/React). But the latter doesn't work with SSR really. Again maybe there should be no expectation here but this is now a must be considered design space. You can't just assume you are dealing with string attributes and be done with it.

              Custom Elements asynchronously upgrade. So you can get an Unknown Element before you get the actual element. Properties could be set without trigger setters, or accessed without triggering getters. This wrecks havoc on solutions that assume synchronous execution (basically all UI frameworks reactivity works off being synchronous). This impacts things like tracking of Signals or availability of Context. These are things we could assume before but no longer. There are also some details related to import vs cloning since when an element receives it's document has impact on behavior, something that if there were this case for native elements we could know about but custom elements... who knows?

              I think at least Custom Elements assume less than the Shadow DOM.. so there is that.. but yeah I wish MutationObservers were all we were dealing with. Think about it.. No one would have an expectation they would work during SSR either because conceptually it is just rendering a page not looking for changes. They wouldn't play into Hydration timing considerations either.

  • Stephen Belovarich
    Stephen BelovarichSep 28, 2024

    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.

    • Ryan Carniato
      Ryan CarniatoApr 8, 2025

      I did link it in the article. I did a fair amount of benchmarking. In case you missed it: dev.to/this-is-learning/the-real-c.... I have other articles as well.

      But it isn't hard to see why this would happen in general. You have lightweight JavaScript functions that renders built in elements competing against components that need to run through the HTML Element interface inorder to operate. You have to go through their life cycle. There is a reason you don't make every object a DOM element. It is a heavier construct. This even happens at the native level.. sometimes setting attributes is more expensive than props. We tend to clone elements instead of creating them one by one because we can offload more work to the underlying engine.

      Just picture no framework and just vanilla JavaScript and HTML. When you can write the code without Custom Elements vs with, the without is going to be faster just because it doesn't have to jump through the hoops. JS Frameworks these days have gotten so efficient with the aid of compilers the overhead over vanilla JS is minimal. These frameworks outperform WCs because they just don't need to go through the same extra steps.

      The cost I refer to though isn't raw performance though. That was never in question. It's the cost of building abstractions on the web and beyond. That is a multi-faceted conversation that takes a lot more details to get into but the summary is the article above.

  • Alex
    AlexSep 29, 2024

    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.

  • Chris Nelson
    Chris NelsonSep 29, 2024

    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.

    • Ryan Carniato
      Ryan CarniatoApr 8, 2025

      There are different sorts of standards. I think sometimes the bigger more ambitious ones in terms of scope can be as damaging as no action. Small impactful things are big. Those can still have huge implications on their own, but if they touch less places you are less likely try to make it into a single vision.

      The problem is mostly this whole thing which was several specs have become "Web Components". They are all designed with each other in consideration. Which on the surface is a good thing, but given the ambition here actually forces a lot of very specific opinions which almost turns this into the exercise of building a framework for the browser. I think that is ill-advised because the rate at which these things evolve.

      That is potentially damaging. I say potentially but it already has been having its impact.

  • Lewis Cowles
    Lewis CowlesSep 30, 2024

    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.

  • oplanre
    oplanreSep 30, 2024

    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.

    • Ryan Carniato
      Ryan CarniatoApr 8, 2025

      How do you render Web Components on the server? DSD is great as output format but not as an authoring format. If you write components that require JavaScript to render properly then you aren't server rendering in your other language. I don't see a problem with just having the webcomponent unrealized on the server and have the client fill it in. It just isn't a great experience when your client experience expands out.. It's like the classic Login screen where the login prompt doesn't appear until the client side JavaScript runs.. it's odd.

      And that's the thing because there is no standardization on the server you could argue they aren't designed to extend HTML as much as the DOM. SSR is actually a really nasty area for WebComponents when you have to consider property serialization, lifecycle events (like if you use native events for Context APIs), and whatever else comes from not having the DOM on the server.

      It's not that I don't see potential value. It is just a miss. Maybe things can get there with specific solutions. But then we are just talking about choosing frameworks. A couple years back when I was working on Marko at eBay we have the Lit devs and WC proponents meet us to talk DSD. My manager was really stoked because he was one of those back to basics, great at accessibility, sort of guys. And he was really intent to see if we could use more WC stuff. And basically the response from the team from Google was that you basically need to use a framework on the server.. And then we were like then why wouldn't we use our own framework that is hyper optimized for server rendering and hydration (eBay's main use case)? And there was no real answer to that.

      If we were talking about good solutions it would be something else, but I've seen much better solutions that don't use this technology and would be hindered by it.

      • oplanre
        oplanreApr 8, 2025

        Hey Ryan, good question — I render Web Components on the server the same way I render any HTML: with Twig, Blade, Go templates, etc. DSD just gives me a standardized way to include Shadow Roots in that output. It’s not magic, but it’s effective.

        You're totally right that DSD is more of a serialization target than something you’d author by hand — and that’s fine by me. I write components in client-side JS where needed, but I’m not trying to use Web Components as a replacement for a full-blown framework. I’m using them to extend HTML, not to build a SPA runtime.

        And sure, hydration, context, and lifecycle events are all tricky if you're trying to treat Web Components like you would Solid or React components. But for my use case — static output, progressive enhancement, small touches of interactivity — that's not really an issue. A login form where the JS enhances behavior rather than renders the entire form? That works great.

        On the topic of frameworks — I don’t necessarily disagree with Google’s take that you can use a framework with Web Components for SSR. But I’d argue the “framework” needed is often so light that it barely counts. Most templating engines can already output the structure you need — the only addition is a bit of glue for the <template shadowroot="open">stuff. You don’t need a VDOM, prop serialization, or hydration script generators. You just render valid HTML and let the browser do its job.

        That’s the core of my point: I’m not locked into a specific toolchain or runtime. I can SSR using PHP, Go, Ruby — whatever fits the project — and my components still work because they’re fundamentally just HTML + a bit of JS. And if I ever want more reactivity, I can layer that in manually, or yes, bring in a more traditional framework.

        I totally get that for apps with complex interactivity and tight performance requirements, using something like Marko or Solid makes more sense. Those frameworks do a fantastic job at optimizing for hydration, state tracking, etc. But for me — and probably a good number of folks just building solid, fast, progressively-enhanced websites — Web Components give me enough of the benefits without needing to buy into the full framework ecosystem or run Node.js in production.

        Appreciate the thoughtful reply. We’re probably optimizing for different goals, but it’s a conversation worth having.

        • Ryan Carniato
          Ryan CarniatoApr 9, 2025

          The problem for eBay was bringing the DOM to server is performance suicide. If React is too slow on the server for big e-commerce so is the DOM. Obviously a non-JavaScript server runtime would be even better but if you need the content of the component to be rendered on the server and also be updated on the client and you have enough complexity to do so declaratively you are going to have tons of logic duplication if you don't run JS on the server. Which takes all the way back to the start and wanting JS on the server to be efficient.

          For what people not using JS on the server need, a element selector and script tag would be sufficient. But the cost of web component support and warping of behavior around them on solutions trying to be isomorphic in JS is a net negative.

          • oplanre
            oplanreApr 10, 2025

            I think you’re framing this in a way that sidesteps what I’m actually advocating for.

            I'm not suggesting you run the DOM on the server. That would be absurd in a non-JS environment, and I agree — trying to SSR with a full DOM emulation layer is a massive performance hit. But that’s not what DSD is. DSD isn’t about simulating the browser — it’s about outputting HTML that the browser already knows how to parse natively, including declarative shadow roots.

            What I’m doing is no different than outputting any old HTML from a server — be it with Twig, Blade, Go templates, take your pick. I’m not serializing props or rehydrating trees. I’m just rendering markup — and yes, some of that markup includes Web Components with DSD. The browser picks up from there. It’s clean, it’s fast, and I can use any language on the server.

            You're acting like if I’m not using JS on the server, I shouldn’t use Web Components at all — that the only valid use case is isomorphic rendering. That’s an incredibly narrow framing. I don’t need my server and client to share rendering logic. I want interoperable HTML with clearly defined boundaries and the flexibility to progressively enhance — and that’s exactly what Web Components + DSD give me.

            And I’m not saying WC is a silver bullet either — I’m just pointing out that it’s a very capable, flexible primitive that works especially well for people not using Node on the server.

            If you think “just use script tags and selectors” is sufficient, cool — but that’s not mutually exclusive with using proper components, encapsulation, and native features like Shadow DOM declaratively. I don’t see why we should throw out Web Components just because they don’t map perfectly to isomorphic JS paradigms. That’s not their fault — that’s a mismatch of expectations.

            • Ryan Carniato
              Ryan CarniatoApr 10, 2025

              If you have web components in the browser you will have some JS logic to render your Shadow DOM. Like if somebody passes some attributes to your custom element that can change the output of your shadow DOM. It can change what attributes you set on those elements or even which elements you choose to show.

              Now I'm on the server and there is no JS and I use the same webcomponent in multiple places with different attributes being set. Now I need to generate different DSD for each impacted attribute combination. I don't have the JavaScript code, so I'm assuming I write the same logic again now in my server templating language?

              This is what I mean by duplication. One perspective could be that you just don't render the Web Component on the server and let the browser take over. Just render the outer tag and be done with it. But if you are rendering the DSD that suggests you have some sort of logic to render it which if applicable on both sides means duplicated logic. Not to mention how to reconcile what is currently in the DSD with future client updates. We basically have hydration.

              This is avoided if you don't ever update client attributes so you don't need the JS code at all. Then you could generate the DSD as you see fit and only write the code in a single language. But wouldn't you think it is a weird expectation to have a primarily client side mechanism with Web Components approach to server rendering basically be don't use the client? I don't know who would expect that.

              There is a certain physics to this all. Unescapable truth that we find over and over. While it could be true that the use cases provided serve value to a great number of people, we should put that against the consequences where these solutions ultimately will find themselves. I'm staring at this contradiction and am concerned.

              • oplanre
                oplanreApr 11, 2025

                “Now I need to generate different DSD for each impacted attribute combination. I don't have the JavaScript code, so I'm assuming I write the same logic again now in my server templating language?”

                Why do you think templating languages exist?

                Seriously — people have been dynamically rendering HTML on the server since the '90s. Twig, Blade, Go templates, Jinja2, take your pick. You're describing basic server-side templating like it's some unsolved mystery. It's not. It’s routine.

                With Declarative Shadow DOM, I’m just rendering HTML. That’s it. If a <user-card> needs to render a different message based on a prop like isOnline, I write that logic in my Go template, just like I would for any other tag. The Web Component’s client-side JS only kicks in after the page loads — for interactivity, not initial structure.

                “Wouldn’t you think it’s a weird expectation to have a primarily client-side mechanism... be don’t use the client?”

                Not really. <details>, <video>, <dialog> — HTML has always included progressively enhanced elements that don’t require JS to render. Web Components extend that tradition. The fact that I can now render custom ones with SSR support is a win, not a flaw.

                “There is a certain physics to this all…”

                Sure — and physics tells me I don’t want to haul a full virtual DOM onto the server when I already have a perfectly good HTML parser and templating engine on the client. I like to respect the DOM, not abuse it by bypassing HTML entirely and going full document.createElement("div") for every child node like I’m in some kind of JS fever dream.

                And yes, for cases where interactivity is needed, I use client-side JS — just like any normal site. But the base content is server-rendered, indexable, fast, and clean. No hydration jank. No 200kb JSON blobs. No illusion of SSR.

                Some people want a server that speaks their language — not JavaScript. Web Components + DSD let me do that without fighting the platform. That’s a good thing.

                • oplanre
                  oplanreApr 11, 2025

                  Are you telling me you can't wrap your head around this? or that it's too much code to write or something?

                  package main
                  
                  import (
                      "html/template"
                      "net/http"
                  )
                  
                  type Product struct {
                      Name   string
                      Price  float64
                      OnSale bool
                  }
                  
                  var tmpl = template.Must(template.New("page").Parse(`
                  <!DOCTYPE html>
                  <html>
                  <head>
                    <title>Store</title>
                    <style>
                      .grid {
                        display: grid;
                        grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
                        gap: 1rem;
                      }
                    </style>
                  </head>
                  <body>
                    <h1>Our Products</h1>
                    <div class="grid">
                      {{range .}}
                        <product-card>
                          <template shadowrootmode="open">
                            <h2>{{.Name}}</h2>
                            <p>Price: ${{.Price}}</p>
                            {{if .OnSale}}
                              <p style="color: red;">On Sale!</p>
                            {{end}}
                          </template>
                        </product-card>
                      {{end}}
                    </div>
                  
                    <script type="module">
                      customElements.define('product-card', class extends HTMLElement {
                        connectedCallback() {
                          if (!this.shadowRoot) {
                            const tpl = this.querySelector('template[shadowrootmode]');
                            if (tpl) {
                              this.attachShadow({ mode: tpl.getAttribute('shadowrootmode') })
                                  .appendChild(tpl.content.cloneNode(true));
                            }
                          }
                        }
                      });
                    </script>
                  </body>
                  </html>
                  `))
                  
                  func handler(w http.ResponseWriter, r *http.Request) {
                      products := []Product{
                          {"Go Hoodie", 39.99, true},
                          {"Rust Socks", 12.50, false},
                          {"Node.js Mug", 18.00, true},
                          {"PHP Hat", 25.00, false},
                      }
                      tmpl.Execute(w, products)
                  }
                  
                  func main() {
                      http.HandleFunc("/", handler)
                      http.ListenAndServe(":8080", nil)
                  }
                  
                  Enter fullscreen mode Exit fullscreen mode
                  • Ryan Carniato
                    Ryan CarniatoApr 11, 2025

                    Thanks for the replying again. I just wanted to confirm it was primarily this low interactivity scenario. Which is fine. I am not suggesting templating is necessarily complicated as a baseline, but if you have 2 templating technologies competing for the same space it gets messy fast. Back in 2010 trying to layer KnockoutJS over Ruby's ERB was a brutal experience.

                    Most modern JS frameworks compile their templating on the server to simple string concatting, no DOM representation needed. So you can write the code once and have it update on both sides. But that does lead to JS on both sides.It doesn't need to be 200kb sites either. There are technologies that leverage JS on both sides to streamline that in ways not possible otherwise. Of course if you no need to scale up the client it isn't neccessary.

                    It's actually the Web Component solutions in this space, like Lit, that are attempting to emulate the DOM on the server. And Webcomponent proponents who are confused why JS frameworks wouldn't want to do that.

                    If you can have the scenario to avoid needing to scale up client complexity that's great. It's a much simpler problem that way. It sort of falls into the HTMX zone of things. Most of my concerns and gripes probably have no bearing on your use case. If WCs were restricted to that there probably wouldn't be an article. It's countless other decisions that impact the client. It sounds like you basically have server authored Web Components. Like the server template language generates them instead of JavaScript, always.

                    Out of curiosity if you'd indulge me. What about the Shadow DOM is compelling in your case? Scoped styles? It sounds like the Component concept in your case otherwise could just stay on the server. Like you could just generate less elements without the client being aware of the concept of components.

                    • oplanre
                      oplanreApr 11, 2025

                      Appreciate the thoughtful reply — and yeah, you’ve mostly got it. I’m not trying to make a pitch for running high-interactivity dashboards purely with declarative Shadow DOM. I’m talking about the other 90% of the web: marketing sites, content-heavy pages, multi-page apps — where most things don't need client-side state reactivity or hydration just to show up properly styled and interactive.

                      What about the Shadow DOM is compelling in your case?

                      So glad you asked.

                      What I love about Shadow DOM — beyond scoped styles — is behavioural encapsulation. I can include JavaScript with real logic (not just onclick handlers) that’s entirely self-contained. It doesn’t leak global state, doesn’t require coordination with the page, and doesn’t need to hijack the entire app structure to work. It’s HTML + attributes in, behaviour out.

                      This is where the misunderstanding often creeps in: I don’t reimplement any logic in my server templates. That’s not the contract. The server generates the markup and provides data — just like it does for literally every templating language since forever. The component JS is the one rendering and handling state.

                      Templating engines exist for a reason — they’re great at generating markup with variables. And JavaScript is great at rendering behaviour. There’s no “duplication” unless you're trying to shoehorn reactivity into the server, which... why would you?

                      Here’s a simple example that shows how the concerns are cleanly separated:


                      🧱 HTML (server-rendered)

                      <comment-box data-post-id="42">
                        <template shadowrootmode="open">
                          <style>
                            form { display: flex; gap: 0.5em; }
                            .comments { margin-top: 1em; }
                          </style>
                          <form>
                            <input name="comment" placeholder="Add a comment..." required />
                            <button type="submit">Post</button>
                          </form>
                          <div class="comments">
                            {{ range .Comments }}
                              <user-comment data-user="{{ .User }}" data-text="{{ .Text }}"></user-comment>
                            {{ end }}
                          </div>
                        </template>
                      </comment-box>
                      
                      Enter fullscreen mode Exit fullscreen mode

                      This is all done on the server — same as you would with <div class="comment">...</div> in ERB, Blade, Go templates, whatever. No mystery here. Just cleaner.


                      ⚙️ JavaScript (client-side logic)

                      customElements.define('user-comment', class extends HTMLElement {
                        constructor() {
                          super();
                          const { user, text } = this.dataset;
                          this.attachShadow({ mode: 'open' }).innerHTML = `
                            <style>.comment { padding: 0.5em 0; border-bottom: 1px solid #ccc; }</style>
                            <div class="comment">
                              <strong>${user}:</strong> ${text}
                            </div>
                          `;
                        }
                      });
                      
                      customElements.define('comment-box', class extends HTMLElement {
                        constructor() {
                          super();
                          const root = this.shadowRoot;
                          const form = root.querySelector('form');
                          const input = form.querySelector('input');
                          const comments = root.querySelector('.comments');
                          const postId = this.dataset.postId;
                      
                          form.addEventListener('submit', async (e) => {
                            e.preventDefault();
                            const res = await fetch(`/api/posts/${postId}/comments`, {
                              method: 'POST',
                              body: JSON.stringify({ text: input.value }),
                              headers: { 'Content-Type': 'application/json' },
                            });
                            const { user, text } = await res.json();
                      
                            const comment = document.createElement('user-comment');
                            comment.dataset.user = user;
                            comment.dataset.text = text;
                            comments.appendChild(comment);
                            input.value = '';
                          });
                        }
                      });
                      
                      Enter fullscreen mode Exit fullscreen mode

                      So yes — the server generates the outer tag and attributes (because... it’s a server), and then the component renders itself and handles interactivity. There’s no messy coordination or duplicate logic — just clear ownership boundaries.

                      This isn’t anti-JS. I like JS. I just don’t want to abuse it by manually constructing DOM trees in JS that the browser’s HTML parser already gave me for free. That’s not efficient or ergonomic. And it’s not necessary.

                      It sounds like you basically have server-authored Web Components.

                      No — I have server-initiated Web Components. The structure comes from the server, but the logic and rendering lives in the component — where it belongs. It’s not "instead of JS," it’s "in cooperation with JS." That's what makes the Shadow DOM compelling — it lets me scale interactivity inside components, not across the whole page.

                      It’s like importing a self-contained widget, not building a distributed system of event bus spaghetti. Which frankly is the actual mess I'm trying to avoid.

                      Let me know if you'd like a fancier example — this stuff scales way better than people think.

                      • Ryan Carniato
                        Ryan CarniatoApr 11, 2025

                        Oh but you aren't server rendering the comments. You are avoiding duplication by choosing a side. Sure comments might not be important enough that they need to be present before JavaScript loads but I'm not sure that is true for everything that is interactive. I did this pattern too back in the day.

                        This scales in the sense you are free to grow the client part as needed but it comes at direct tradeoff of what can be server rendered. Given the amount of interactivity and laziness of developers we just saw the client part grow to absorb most of the page.

                        It's funny React Server Components are going through this same struggle right now, as they are similar to this pattern woth server only components weaving in client components except the client stuff is also Server rendered initially. You'd think this might be the best of both worlds but again as dynamicism scales up the server page model for mutation drives most things client. That and React implementation is incredibly bloated. I actually prototyped a 5kb version of this mechanism but wasn't content and put it aside.

                        Anyway sorry I tangented. I can see how this can do the trick. I do think isomorphism being able server render everything has considerable benefit. But it might not be needed for everything. I do sometimes feel this stuff has all gotten too complicated. But then I remember we still haven't created an ideal solution that works across the board and get back to it. It's just too bad Web Components aren't really helping and are by existing hindering this. But I admit a server first argument was a new one and I appreciate you sharing.

                        • oplanre
                          oplanreApr 11, 2025

                          Oh, I see — you’re not objecting to duplication so much as objecting to me not duplicating in the exact way you expected. Got it.

                          But respectfully, this “you’re just choosing a side” framing kind of misses the forest for the trees. What I’m doing is choosing boundaries, on purpose. The server owns data and structure. The client owns behavior — per component, in isolation, with no global bootstrapping or coordination. That’s not a workaround, that’s the entire point.

                          You talk about how the client “absorbs” more and more responsibility — but why is that always treated as inevitable? Are we scaling complexity because our use case demands it, or because our tooling defaults to it? If your answer to “I want a dropdown” is to hydrate the whole page with a VDOM, maybe you’re not scaling so much as surrendering.

                          And yeah, sure, React Server Components are chasing this same “split” idea — but through a five-layer abstraction maze with build pipelines and execution contexts that need their own glossary. I get the appeal if you’re already deep in that ecosystem. But let’s not pretend it’s the only, or even the most elegant, answer.

                          You seem nostalgic for a world where everything is isomorphic, the client is fully reactive, and duplication is solved by running the server again… in the browser. That’s fine. But maybe — just maybe — the answer isn’t to push everything into JS land. Maybe we’re just so used to our tools making everything client-first that we forgot how the platform actually works.

                          And then Web Components come along, working with the platform instead of against it, and somehow that’s “hindering”? If scoped behaviour, declarative HTML, and actual encapsulation are slowing down your architecture — you might want to ask who’s really getting in whose way.

                          You said it yourself: “we still haven’t created an ideal solution.” But maybe that’s because we keep trying to shoehorn everything into one model — when the web is already designed for multiple.

                          So if you ever get tired of rehydrating HTML you already rendered once, there’s a seat waiting over here. We even have real buttons.

                          • Ryan Carniato
                            Ryan CarniatoApr 11, 2025

                            We don't need to run the full server again the browser. I don't know of you've seen resumability as presented by Qwik. We were working on a very similar idea at eBay. There is still plenty of space to explore in the isomorphic space. Whereas the split space is much older and nothing has really changed of late except finding ways to get isomorphism in there.

                            No one is forgetting how anything works. Just not accepting limitations. Not nostalgia either. I'm always in search for the best solutions. Empirically. But even so it isn't that hard to argue it'd probably be better to server render all the content if it can improve load feel and metrics vs wait for JS to load. There are characteristics that are obvious to lead to better experience.

                            The gripe with web components has to do with side effects of those extensions. Framework authors are browser hackers trying get every last bit of juice out of what's there. If something is faster, smaller, better we will 100% use it. It is in our best interest as only through that are certain capabilities present. And yet this response. I think it says a lot.

                            There isn't something we are missing here. Its why I like having conversations like this time to time to make sure. The last thing I want to do is assume too much.

                            React is bloated sure and there are reasons for it. I'd never claim that is the ideal but atleast they are trying. The target at this point is atleast describable. It's known enough to know what definitely misses the mark and where potential is.

                            The whole when I get tired thing sounds about right. If I was tired a decade ago I would have stayed with my old ways and may have held a similar opinion. But there is so much more that can be done.

                            • oplanre
                              oplanreApr 11, 2025

                              Resumability is cute, but it’s still the same game: pretending the browser is an extension of your server runtime — only now you serialize and sprinkle just enough state over the page to rehydrate later. Sure, you might reduce JS cost upfront. But at the end of the day, you're still wiring the entire app through an abstract runtime instead of leaning on the one that already exists: the DOM.

                              You keep saying “we don’t need to run the full server in the browser,” but that’s exactly what happens — conceptually and often literally. You carry the cost of abstraction, hydration logic, virtual memory models, and declarative synchronization, just so you can feel like the browser is your framework’s VM.

                              Meanwhile, people act like avoiding this mess is some outdated relic, instead of just recognizing that server and client have fundamentally different roles. The split model may be older, but that’s because it works. It's stable. Predictable. And doesn't break every time your dependency tree uses something that’s only available in one environment.

                              “The gripe with Web Components has to do with side effects of those extensions.”

                              This says more about framework internals than Web Components. Native platform APIs having side effects is expected — frameworks wrapping every interaction in reactive proxies and schedulers is the weird part. If your whole stack starts breaking the moment something escapes your VDOM bubble, maybe the architecture isn’t as robust as advertised.

                              “React is bloated sure... but at least they are trying.”

                              Trying to what? Recreate the browser? Rediscover that the DOM is a perfectly good reactive UI system if you stop fighting it?

                              “If I was tired a decade ago I would have stayed with my old ways…”

                              Honestly, I just got tired of pretending the new ways were better. Of wasting time debugging weird hydration mismatches, VDOM diffing bugs, overengineered suspense semantics, and playing dependency roulette because someone’s “universal” library used window on line 12.

                              I’m not against progress. But most of what’s branded as progress here feels like machinery built to patch over poor boundaries. All the complexity, just to get back to fast, structured, portable HTML — the very thing the browser was already good at.

                              And when you say “there’s still plenty to explore in the isomorphic space,” sure. But exploration without subtraction just leads to bigger ships with more holes. At some point, the map isn’t the territory — and a better UX doesn’t come from more JavaScript pretending it’s something else.

  • Herve Tribouilloy
    Herve TribouilloyOct 1, 2024

    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.

  • Mr.P
    Mr.POct 2, 2024

    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

  • Andrew Jackson (Ajax)
    Andrew Jackson (Ajax)Oct 3, 2024

    I've written 4 sites in uncompiled LitHTML and it's a relief:

    • No package.json to be found, nor compilers, nor debug-plugins, faster releases
    • 🐛 Native Browser Debugging without tricks
    • ⚡Performance: -- the 4kB LitHTML load = less JS scaffolding and more browser-direct code. -- Free hydration💧: The first page doesn't load the whole SPA.
    • Single-Page Apps just need simple routers I could write myself or debug into.
    • Minification is transparent through CloudFlare.
    • Cache Friendly: 90% of the files between releases are the same.
    • components/ services/ and views/ folders = SPAs as tidy as React/Vue/Svelte
  • Dmitri Smirnov
    Dmitri SmirnovOct 8, 2024

    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 ;).

    • Ryan Carniato
      Ryan CarniatoOct 8, 2024

      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.

  • Y S
    Y SOct 8, 2024

    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.

  • martin rojas
    martin rojasOct 10, 2024

    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.

  • O S
    O SOct 11, 2024

    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. 😉

    • Ryan Carniato
      Ryan CarniatoApr 8, 2025

      I realized that my article makes more sense to people already deeply familiar with these things. WCs don't make frameworks redundant, and they don't really do the same things. The problem isn't whether one can solve these issues, but whether it makes sense to. It's largely just a case of wrong abstraction and a gap between reality and the conclusion one would make if doing simple exploration. Having been embedded in this for over a decade it was ambitious to try put that all to paper in a single go.

      So you are right. I did write this article almost completely in a couple hours a single "rant". Yet when I re-read it it still hits exactly the points and pacing I intended. That being said it is definitely more of a rant. I'm not going suggest that my other writing is much better but there is a lot of information and you won't find elsewhere there given my specific experience. So if you do come across some other topic I've written maybe give it a chance as I don't think this article is the most representative.

      The challenge I had with approaching this article is nitpicking on the details is pointless because there are too many. And proponents of WC will get you arguing about how they are going to solve problem X or Y. I needed to include enough examples to carry my narrative, but not get any more mired in the details. Otherwise I don't think you'd even been able to finish.

  • Lars Rye Jeppesen
    Lars Rye JeppesenOct 25, 2024

    This is an article about React, by a React developer, for React developers. As React devs do.

  • Vaishnav Deore
    Vaishnav DeoreOct 25, 2024

    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

  • Zachary Hamm
    Zachary HammNov 25, 2024

    One thing that I'd love to see as a followup is that if web components is not the answer (as there is never truly one for web design), in which direction do we look next? These attempt to answer a problem that existed previously when building websites before them. Eventually, someone will create something to address their own problem, and then it gets adopted as because a ton others had a similar enough issue. It seems that standardizations are given life after people using the same new platform based on how widely available and utilized it is to keep up with their work environment; no one wants to miss the train. Then, it's either let everyone keep building their house on sand, or develop rules to which all must be conform to avoid the pitfalls of whatever problems arise with new solutions. Whereas regulations are written in blood, web standardizations come from 10,000 diverging patterns to try and guide people to treading a same path.

    I often say that in this field things are discovered as much as they are invented. What I mean by that is there is a certain truth/physics, if you will, to design decisions that when followed lead us all to similar places. It isn't that these tools copy each other blatantly. They fall into the grooves.

    Programming really isn't different from other STEM fields and it is not on a pedestal above the others, either. Let's prevent pretending it is. It's still engineering. Science is all about discovery and making conclusions based on such, until a theory can be created to describe it as being a uniform pattern. In short, agreed standards are going to come out of making sense of things and that applies across each of those fields. With web design, there's so much open ground because we're still finding ways to present information with ubiquity.

    Most websites really look the same, and nowadays need to present in both desktop and mobile formats. It's an inherent agreement to keep doing this now. That alone adds to the stress of finding ways to provide a user experience that is ubiquitous to anyone with a browser. Web components kind of make sense in a case like this since they have the ability for one to provide an experience that works on both formats while using the same inputs and data to produce differing outputs depending on a viewport. To say that web components add to the list of things to keep updated in an application is just a piece of the total environment that to which one conforms when building a website.

    I could be incorrect, but I don't think that the web was the first place that design components arose, either. Early mobile apps seem to create that implicit standardization that led to where we are today. Android had its own design system with components: to build an app for that platform meant that you needed to use what they gave you, so you were stuck with the tradeoffs having access to only those components. It was the same for iOS. Only recently have I noticed apps on both platforms seem to drift towards their organization's design systems and away from their hosts' design systems. That's most likely because the early standardization has now led to more freedom in choosing how to build and style their apps while still using the underlying mobile APIs. Web APIs try to answer the same question -- for a complete developer, designer, and user experience, there needs to be some semblance of uniformity and accessibility for all types of people who interact with the application. Web components are a pattern that allows for that while integrated into the framework.

    I'm not agreeing that web components are the next level towards standardization, but what else is? Right now, I personally prefer them over just HTML or just frameworks because I don't need to build my own common patterns. At that point then we end up with another new JS framework. I want ubiquity in the basics so I don't need to spend more time creating them. With every enhancement comes a tradeoff, but is the value of that tradeoff worse than the issues we'd continue to have without them?

    • Ryan Carniato
      Ryan CarniatoApr 8, 2025

      I guess it is interesting because the web didn't have Web Components for the first ~20 years. Or atleast it only had a very specific set of elements. My major gripe has been that using elements for components ties it too much to the templating and the lifecycles of the underlying platform when these things don't need to be.

      Frameworks went through a phase where they really embraced Web Components because they thought it would allow them to be lighter weight and focus on something else. But then we realized they didn't offer what we needed, and more so that they interfered with the assumptions we could make. I think a lot of this is thanks to Frameworks moving beyond the browser. SSR was a catalyst but mobile and other platforms helped us find even more general patterns. These days I think of things like HTML or even the DOM to a degree as a serialization format. An output. And this gives us more control so having the platform introduce more mechanisms to get in the way of that just makes everything messier.

      We know that WCs aren't set up to be that generalizable thing, even when considering server rendering and hydration. So it would be nice to step back and look at what pieces are important.

  • Michael M
    Michael MNov 26, 2024

    Web Components are not a replacement for React, Vue or KO but a way to make cross framework components. They are cumbersome but I do see the value in using them for small reusable elements.

  • Anthony
    AnthonyDec 11, 2024

    Every time I'm trying to do Web dev. now turns to disaster (despite the fact that in the past I did that already, in times of good old server-side rendering).

    Now that I pretend to see the reason: browsers are just terrible platform for software development (did you noticed that "software" term?). We, as a whole humanity, did big mistake trying to pretend otherwise. Browsers lacks all major components to do real software development: they lacks language (JS is just a noodles of random ideas took from other languages at the time of it's invention, but without consistency among them), they lack linker (which is responsible for proper reuse of already written code), they lack packages facility (which is responsible for distribution of that written code), and they lack REPL (which is responsible for feedback and prototyping) (yes, there is console in browsers, but it is just an incarnation of VT in browser - it is not REPL. Don't believe me? Try to load and execute just single piece of code in browser. Ugh... You need a server in order to do that. Isn't that an insane? Do you know any other language which requires a server only for executing you code? I know that - it is PHP. So, JS is "PHP in browser" - they are compare quite par each other). And I'm quiet about editor...

    We must redo it from clean.

  • George
    GeorgeJan 12, 2025

    Думаю что с приходом GPT генераторов низкоуровневые абстракции элементов не нуждаются в оборачивании удобными для человеков абстракциями фреймворков.
    Уменьшение сложности, которое требовалось для людей, совсем не нужно для систем генерации. В таком мире востребованность отлаженных веб компонентов должна возрасти, а использование фреймворков уменьшиться.

    I think that with the advent of GPT generators, low-level element abstractions do not need to be wrapped in human-friendly framework abstractions.
    The complexity reduction that was required for humans is not needed at all for generation systems. In such a world, the demand for debugged web components should increase, and the use of frameworks should decrease.

  • Kelly Taylor
    Kelly TaylorFeb 5, 2025

    This article is purely written from the viewpoint of a JavaScript framework developer. The real value or promise of standalone web component is that it can provide uniform behavior and look for the frontend UI of PHP, Python, Java, or Perl, instead of relying on JQuery for user friendly IO, or re-rendering pages from the server. Legacy systems often have several language systems. If React was used for some standalone web components, it would be a gateway for migrating from one of the legacy server systems to Remix or NextJS, and/or give legacy developers some Remix exposure. With no resources familiar with React, the chances of migrating are nill.

  • Javi Aguilar
    Javi AguilarMar 30, 2025

    I hope that 15 years from now many of these web component APIs will be deprecated and something better will be the standard, more close to how we build applications with other frameworks, something we can build declaratively in the server as well. I would make shadow DOM optional for building web components, and create a first-class Web Components API.

    Imagine something like this is supported:

    <!-- This is a component blueprint, not an instance -->
    <component name="my-component">
      <div slotprops="title" class="text-sm"><slot name="title" /></div>
      <button id="btn1" slotprops="btn" class="bg-primary p-2 text-center">
          <slot name="btn" />
       <button>
       <script scope="component">
          // this, references the current component instance
          this.connectedCallback = () => { /* on mount*/ }
          // direct DOM references:
          this.btn1.onClick = () => {console.log('clicked')}
       <script>
    </component>
    
    Enter fullscreen mode Exit fullscreen mode
    <head>
    <link rel="component" src="my-component.html" />
    </head>
    <body>
    <my-component>
      <slot name="title" class="text-xl">Hello world!</slot>
      <slot name="btn">Send message</slot>
    </my-component>
    </body>
    
    Enter fullscreen mode Exit fullscreen mode
Add comment