The Web Component Success Story

Tom MacWright wrote a short post wondering why we don’t see prominent applications using web components On Web Components macwright.com/2024/01/24/on-web-components .

That’s a fair question! It’s easy to see the success of frameworks like React and Rails: just look at the thousands of websites built with them. What does the web component success story look like?

Contrary to some people, I don’t see web components on their own as a huge productivity boon for individual websites. Once you’ve bought into a particular set of technologies, it makes sense to use it for as much as you can. If you have a React app, you’d be justifiably skeptical of introducing a second way to build components!

Rather, the biggest benefits I see are collective, cutting across the industry as a whole. I think web components can make the entire web more accessible. They have the potential to unify currently fragmented communities, including various JavaScript frameworks and those who avoid them.

I know that’s an audacious pitch, but bear with me.

JavaScript Framework Interop

Whenever I write about web components, I see pushback from people in the JavaScript community who seem to think that I want replace to JavaScript frameworks.

If you’re in that camp, let me assuage those fears: the web component success story emphatically does not involve rewriting every React app using web components. As I’ll continue to say, web components and JavaScript frameworks are complementary (as opposed to competing) technologies. In fact, I think JavaScript framework apps will be one of the most common places in which web components are used!

Does that mean we’ll all start writing web components in addition to React components? Not at all. When I say that web components will be used in JavaScript framework apps, I’m talking about third-party libraries.

JavaScript frameworks are tools, all tools have tradeoffs, yada yada, let’s skip the preamble. I want to talk about one specific weakness of JavaScript frameworks: interoperability, or the lack thereof. Almost without exception, each framework can only render components written for that framework specifically.

As a result, the JavaScript community tends to fragment itself along framework lines. Switching frameworks has a high cost, especially when moving to a less popular one; it means leaving most of the third-party ecosystem behind.

That switching cost stunts framework innovation by heavily favoring incumbents with large ecosystems. It’s hard to create new frameworks, because each one has to start its own ecosystem from scratch. We keep rebuilding the same set of primitives over and over and over again.

There’s a famous Joel Spolsky blog post about why capitalistic tech companies contribute to open source Strategy Letter V When I was in college I took two intro economics courses: macroeconomics and microeconomics. Macro was full of theories like “low unemployment causes inflation” that never quite stood u… www.joelonsoftware.com/2002/06/12/strategy-letter-v/ . Briefly: every product has substitutes (products that can replace it) and complements (products that can be used alongside it). The big takeaway is that ”smart companies try to commoditize their products’ complements”. In other words, they try to make it so that their own product has a proprietary advantage, while the products used alongside it are all cheap and interchangeable.

Back to JavaScript frameworks. React and Svelte are substitutes, while React and Radix are complements. As a library author, the way to commoditize your complement is to make it work with as many frameworks as possible.1 And unlike in Native Land — where people have collectively spent billions of dollars over decades developing write-once run-anywhere environments — the web has one built in.

Maybe you’ve heard of it? It’s called HTML, and it works with every Javascript framework Custom Elements Everywhere Making sure frameworks and custom elements can be BFFs 🍻 custom-elements-everywhere.com . For all their warts, the fact that web components get this interoperability for free is a ridiculously powerful advantage, and libraries that don’t exploit it are leaving a lot of potential users on the table.

Here’s a concrete example. xyflow Node Based UIs for React and Svelte – xyflow Powerful open source libraries for building node-based UIs with React or Svelte. Ready out-of-the-box and infinitely customizable. www.xyflow.com is an excellent library for making flow charts. It was originally called React Flow, but the maintainers renamed it when they added Svelte support. They had to put in a ton of work just to support that one extra framework Why Svelte Flow? – xyflow xyflow - Customizable library for rendering workflows, diagrams and node-based UIs. www.xyflow.com/blog/why-svelte-flow ! And if you use Vue, Angular, Solid, Qwik or Ember, you’re still out of luck.

React has enjoyed continued success because it has a moat of fantastic third-party libraries: Radix, React Aria, React Three Fiber, Framer Motion and xyflow, among many others. Web components have the potential to give us that same ecosystem — but for every framework.

Islands of Interactivity

Of course, plenty of websites don’t use JavaScript frameworks. Hypermedia-centric approaches (read: how websites were built before circa 2010) are making a resurgence, led by libraries such as htmx.

Many websites like this still incorporate highly dynamic elements. Often, these take the form of rich widgets that are missing from HTML, like menus and combo boxes. Sometimes they’re even more complicated, like interactive diagrams in articles. The modern term for these dynamic regions within an otherwise static page is “islands of interactivity”, but the pattern has existed for a long time.

Embedding these islands within the larger page has always been kinda awkward. The process remains mostly unchanged from the days of jQuery plugins, relying on a complex choreography of HTML classes, CSS selectors and JavaScript function calls. The bulk of the setup happens in a separate JavaScript file, far away from the HTML where the component will live on the page.

Web components invert that process. They allow islands to be instantiated in the same way as any other element: by writing a tag name in the page’s markup. As I wrote in The Website vs. Web App Dichotomy Doesn’t Exist The Website vs. Web App Dichotomy Doesn't Exist | jakelazaroff.com A one-dimensional spectrum can't sufficiently capture the tradeoffs involved in web development. jakelazaroff.com/words/the-website-vs-web-app-dichotomy-doesnt-exist/ , web components allow developers to declaratively add dynamic behavior to HTML itself.

What makes web components particularly good companions for hypermedia-oriented libraries is the way they interact with other parts of the page. While JavaScript framework components tend to do so by invoking callback functions, web components instead embrace one of the web’s core idioms: events. 2 Indeed, Carson Gross’s essay Hypermedia-Friendly Scripting </> htmx ~ Hypermedia-Friendly Scripting htmx.org/essays/hypermedia-friendly-scripting/#events neatly outlines this use case:

A JavaScript-based component that triggers events allows for hypermedia-oriented JavaScript libraries, such as htmx, to listen for those events and trigger hypermedia exchanges. This, in turn, makes any JavaScript library a potential hypermedia control, able to drive the Hypermedia-Driven Application via user-selected actions.

As an example, here’s a TIL I wrote on using htmx and the Shoelace web component library to load the content of a dialog when it opens [htmx] Load modal content when a Shoelace dialog opens | Today I Learned A collection of useful things I've learned. til.jakelazaroff.com/htmx/load-modal-content-when-shoelace-dialog-opens/ . Notice how the whole process — from instantiating the dialog component, to requesting the content when the modal opens, to inserting it into the appropriate place in the DOM — is controlled declaratively via markup.

There are also HTML web components An Attempted Taxonomy of Web Components—zachleat.com A post by Zach Leatherman (zachleat) www.zachleat.com/web/a-taxonomy-of-web-component-types/#html-web-components , which work by progressively enhancing existing markup rather than by rendering new DOM elements. Colocating logic in this way, sometimes called locality of behavior </> htmx ~ Locality of Behaviour (LoB) htmx gives you access to AJAX, CSS Transitions, WebSockets and Server Sent Events directly in HTML, using attributes, so you can build modern user interfaces with the simplicity and power of hypertext htmx is small (~14k min.gz’d), dependency-free, extendable, IE11 compatible & has reduced code base sizes by 67% when compared with react htmx.org/essays/locality-of-behaviour/ , is a different lens on a concept with which JavaScript developers should already be familiar Let There Be Peace On CSS In the last few months there's been a growing friction between those who see CSS as an untouchable layer in the "separation of concerns" paradigm, and those who have simply ignored this golden rule and found different ways to style the UI (typically applying CSS styles via JavaScript). This debate is getting more and more intense every day, bringing division in a community that used to be immune to this kind of “wars”. This talk is my attempt to bring peace between the two fronts. To help these two opposite factions to understand and listen to each other, see the counterpart's points of views. To find the good things they have in common, and learn something from that. ## This talk has been presented at London CSS Meetup + Design Exchange Nottingham (DXN) + Front End London (FEL) + State of The Browser ## Video of the talk: https://www.youtube.com/watch?v=bb_kb6Q2Kdc speakerdeck.com/didoo/let-there-be-peace-on-css?slide=62 .

No More Silos

These sound like separate problems, but they’re actually two sides of the same coin. With web components, the library that works in every JavaScript framework also works as an island of interactivity on a static webpage. Even HTML web components fit into both niches.

Brad Frost has called for a global design system A Global Design System TL;DR: This is a call to action to create a Global Design System that provides the world's web designers & developers a library of common UI components. A Global Design System would improve the quality and accessibility of the world's web experiences, save the world's web designers and developer bradfrost.com/blog/post/a-global-design-system/ : “a common library containing common UI components currently found in most design systems”. The proposal is to create a cohesive, unstyled, accessible and internationalizable set of components — like Radix Radix Primitives Unstyled, accessible, open source React primitives for high-quality web apps and design systems. www.radix-ui.com/primitives , but for the entire web rather than for a single JavaScript framework. It’s an ambitious goal, and from where I stand web components are by far the best way to achieve it.

Web components won’t take web development by storm, or show us the One True Way to build websites. They don’t need to dethrone JavaScript frameworks. We probably won’t even all learn how to write them!

What web components will do — at least, I hope — is let us collectively build a rich ecosystem of dynamic components that work with any web stack. No more silos. That’s the web component success story.

Footnotes

  1. Meta understands this, which is why they built React Native. Frameworks are a complement of platforms, and the way to commoditize platforms is to make your framework run on as many of them as possible.

  2. It’s worth mentioning that the islands approach doesn’t mean foregoing JavaScript frameworks. I showed in Web Components Eliminate JavaScript Framework Lock-in Web Components Eliminate JavaScript Framework Lock-in | jakelazaroff.com Web components can dramatically loosen the coupling of JavaScript frameworks. To prove it, we're going to do something kinda crazy: build an app where every single component is written in a different JavaScript framework. jakelazaroff.com/words/web-components-eliminate-javascript-framework-lock-in/ how web components can be used together with JavaScript frameworks as a decoupling tool. Some frameworks even support compiling to web components out of the box. The upshot is that it’s easy to use a JavaScript framework to build your islands.