The Case for Web Components
Tags: webcomponents, webdev, javascript
Published: 2022-04-14 18:57:36

From late 2018 to - at the time of this writing - 2022, I've found myself advocating and defending web components. This advocacy stems from framework fatigue induced by switching from jQuery to Sencha ExtJS to Angular to React to Svelte. For the most part, each framework has brought with it a DSL one needs to acquire to use effectively, but which is rendered obsolete when one begins working with a new framework.

Generally, **a framework is collection of design patterns coupled with a means of enforcing them.** If you've built your application right (think hexagonal architectures), you should be able to port your application from one framework to another without having to touch the majority of the codebase.

**Web UI frameworks aren't like other frameworks because in addition to a collection of design patterns, they also provide a means of composing reusable widgets from atomic, native elements.** This means of composition is unique to each framework, even when they have a common DSL like JSX. The uniqueness of each framework's composition mechanism means that widgets built in one framework cannot be ported to another.

**Frameworks come and go**, and on a platform that's evolving as quickly as the web browser, this is truer than most. The framework du jour might seem irreplaceable now, but at some point in the course of your project, you will run into limitations that have been solved by a newer framework. The limiting factor at that time becomes the cost of rebuilding your existing widgets for the new framework; try explaining to management why they need to fund, and allocate time for, the construction of UIs they already paid for. And even when they're willing, engineers can hardly be expected to be excited about the prospect of building the same UI again. Switching to a new framework this way is effectively a rewrite, and a rewrite brings with it the risk of recreating defects the team has already fixed.

So, understandably, management and engineering leadership express reticence at the prospect of a framework change. And as engineers struggle with fitting newer patterns into a framework that wasn't designed to support them, the quality of the codebase declines, leading to more defects and reduced team velocity. This in turn lowers confidence, which increases resistance to the idea of attempting a framework driven rewrite. The downward spiral continues until the cost of maintaining the codebase is judged equal to, or in excess of, that of rewriting the web application. The framework du jour is now eagerly embraced, and the cycle begins anew.

If one accepts that a framework change is inevitable (and perhaps even desirable) in a long living codebase, then a team's focus should be on **minimizing the cost of a framework switch**. Web Components offer a means to this end. They are a collection of four specifications ([Custom Elements](https://w3c.github.io/webcomponents/spec/custom/), [Shadow DOM](https://w3c.github.io/webcomponents/spec/shadow/), [ES Modules](https://html.spec.whatwg.org/multipage/webappapis.html#integration-with-the-javascript-module-system) and [HTML Templates](https://html.spec.whatwg.org/multipage/scripting.html#the-template-element/)) that collectively provide a means to building and deploying reusable widgets. A web component can be built once, and used across applications built with different frameworks. And because these are standards, they are less likely to be rendered obsolete, and are guaranteed to be supported across all modern web browsers.

While you can build components directly from the supporting Web APIs, you might find it productive to use a library that's been built to support this task. [Lit](https://lit.dev) and [StencilJS](https://stenciljs.com) are two of several libraries with acompanying tooling to help you build web components. And because they compile to the same 'target', they give you an additonal advantage: if you choose to switch web component libraries at some point in the future, you can make the switch for new components without having to rewrite the old ones, and use both in the same application.

## References
 - The [Custom Element](https://w3c.github.io/webcomponents/spec/custom/) specification
 - The [Shadow DOM](https://w3c.github.io/webcomponents/spec/shadow/) specification
 - The [ES Module](https://html.spec.whatwg.org/multipage/webappapis.html#integration-with-the-javascript-module-system) specification
 - The [HTML Template](https://html.spec.whatwg.org/multipage/scripting.html#the-template-element/) specification
 - [Lit](https://lit.dev)
 - [StencilJS](https://stenciljs.com)