Web Components Will Outlive Your JavaScript Framework
Jake Lazaroff
October 25, 2023
If you're anything like me, when you're starting a project, there's a paralyzing period of indecision while you try to figure out how to build it. In the JavaScript world, that usually boils down to picking a framework. Do you go with Ol' Reliable, a.k.a. React? Something slimmer and trendier, like Svelte or Solid? How about kicking it old school with a server-side framework and htmx?
When I was writing my CRDT blog post series, I knew I wanted to include interactive demos to illustrate the concepts. Here's an example: a toy collaborative pixel art editor.
Even though I've written before — and still believe — that React is a good default option, the constraints of a project should determine the technology decisions. In this case, I chose to use vanilla JS web components. I want to talk about why.
There was one guiding principle for this project: although they happened to be built with HTML, CSS and JS, these examples were content, not code. In other words, they'd be handled more or less the same as any image or video I would include in my blog posts. They should be portable to any place in which I can render HTML.
As of 2023, this blog is built with Astro. Before that, it was built with my own static site generator. Before that, Hugo; before that, a custom CMS written in PHP; before that, Tumblr, Movable Type and WordPress — and I'm sure I'm missing some in between. I really like Astro, but it's reasonable to assume that this website won't run on it forever.
One thing that has made these migrations easier in recent years is keeping all my content in plain text files written in Markdown. Rather than dealing with the invariably convoluted process of moving my content between systems — exporting it from one, importing it into another, fixing any incompatibilities, maybe removing some things that I can't find a way to port over — I drop my Markdown files into the new website and it mostly Just Works.
Most website generators have a way to include more complex markup within your content, and Astro is no different. The MDX integration allows you to render Astro components within your Markdown files. Those components have access to all the niceties of the Astro build system: you can write HTML, CSS and JS within one file, and Astro will automagically extract and optimize everything for you. It will scope CSS selectors and compile TypeScript and let you conditionally render markup and do all sorts of other fancy stuff.
The drawback, of course, is that it all only works inside Astro. In order to switch to a different site generator, I'd have to rewrite those components. I might need to split up the HTML, CSS and JS, or configure a new build system, or find a new way to scope styles. So Astro-specific features were off limits — no matter how convenient.
But Markdown has a secret weapon: you can write HTML inside of it! That means any fancy interactive diagrams I wanted to add would be just as portable as my the rest of my Markdown as long as I could express them as plain HTML tags.
Web components hit that nail square on the head. They're a set of W3C standards for building reusable HTML elements. You use them by writing a class for a custom element, registering a tag name and using it in your markup. Here's how I embedded that pixel art editor before:
That's the honest-to-goodness HTML I have in the Markdown for this post. That's it! There's no special setup; I don't have to remember to put specific elements on the page before calling a function or load a bunch of extra resources. Of course, I do need to keep the JS files around and link to them with a
Discussion in the ATmosphere