Essential Web Components
Concise plain-speak about web components.
What are web components?
"Web components" is a loose term used to reference a set of evolving browser APIs and technologies that can be used to create custom HTML elements.
Restated more clearly: Web components are HTML elements. From the browsers
perspective, a web component is just as much an HTML element as a <p>
or
<div>
element.
The implications of this are extremely important. Web components do not follow the same rules, conventions, and mental models of a "component" you might find in React, Svelte, or Vue. Instead they follow the rules, conventions, and mental models of HTML elements.
Why would I want to use web components?
Since web components are HTML elements they represent a browser native way of creating reusable UI that can be used just about anywhere you can write HTML.
One of the big motivations of web components is the idea that you can build a set of UI elements that can be used again and again in your projects even if the underlying web framework or technology stack you use changes over time.
Will web components replace my web framework?
No. In an ideal world they should work together.
At its core, web components only provide a way of grouping reusable chunks of UI and behavior. As of 2024, they provide no APIs for routing, reactive data, templating syntax, and so on, like you might find in a modern web framework.
When should I use web components?
The answer can vary a bit depending on who you ask.
One of the most prominent use cases is to build web framework independent design systems and component libraries. Check out Shoelace as a great example of a very mature web component library.
Others like to selectively build and use web components to serve as islands of interactivity within static web pages. Fun fact: Web components are so well suited to the islands architecture it’s how the Astro web framework implements their islands architecture.
And others, still, choose to build entire applications using web components. For example, see Photoshop, Reddit (inspect code), YouTube (inspect code), Microsoft Edge, and Firefox.
Who uses web components?
A lot of people and organizations.
- Adobe
- Amazon
- Apple
- Firefox
- GitHub
- Microsoft
- NASA
- Salesforce
- SpaceX
- Stripe
- YouTube
- Even more companies/projects
What does a web component look like?
From the perspective of a web component consumer, they look like HTML elements with some special differences. Specifically, to avoid naming collisions with regular HTML elements, all custom elements must follow a few rules:
- Starts with a lowercase ASCII character
- Contains at least one hyphen
- Does not contain uppercase ASCII characters
- Does not contain some special characters as defined by the spec
For example, these would be valid web components:
<my-component></my-component>
<my-other-component></my-other-component>
// Even this is valid (although maybe not recommended)
<c-></c->
And these would be invalid web components:
<MyComponent></MyComponent>
<my_component></my_component>
<mycomponent></mycomponent>
From the perspective of a web component author, they look like JavaScript classes that
extend the native HTMLElement
interface.
The Custom Elements API is the JavaScript API responsible for making this happen. It is the absolute bare minimum you need to build a web component. Here's an example:
class MyComponent extends HTMLElement {
constructor() {
super();
}
}
customElements.define('my-component', MyComponent);
This web component renders nothing and has no functionality. But it is a web component. It is an HTML element.
Beyond registering custom HTML elements with the browser, the Custom Elements API also provides several component lifecycle methods that let you define custom behavior when a component is:
- Added to a page
- Removed from a page
- Moved to a new page
There is also a lifecycle method for when a component attribute has been changed, added, removed, or replaced.
How do you architect a web component?
There are two major ways of architecting a web component. These two methods are commonly referred to as “HTML Web Components” and “JavaScript Web Components.”
HTML Web Components are perhaps the simpler and more flexible way of building web components. The core premise of HTML Web Components is to write plain HTML and then wrap the parts you want to be interactive using a custom element.
These components only use the Custom Elements API and do not use any other APIs you might find in the “web components” bucket. They look like this:
<counter-button>
<button>Clicked <span>0</span> times</button>
</counter-button>
In other words, an HTML Web Component will hydrate/progressively enhance existing HTML.
JavaScript Web Components, on the other hand, are historically what most people would think of as “regular” web components. They use a wider variety of web component APIs, such as Shadow DOM or templates. They look like this:
<counter-button></counter-button>
In other words, JavaScript Web Component will dynamically generate UI at runtime, similar to single-page application (SPA) components.
There are benefits and drawbacks to both models, so it’s usually a case of picking the right tool (read: architecture) for the right job.
What other APIs make up web components?
The Custom Elements, Shadow DOM, and template APIs are only three of an ever-evolving set of APIs that can be used to build web components. There are several fantastic resources to learn more about other web component APIs that are currently available, being worked on, and proposed for the future.
See the 2023 State of Web Components by Rob Eisenberg (a prominent contributor to the web component space). It's the most recent and comprehensive overview of web component APIs.
Also check out the yearly reports from Web Component Community Group, which include the web component APIs that have been proposed to browser vendors for implementation.
How do new web component APIs get added?
Just like any other browser API, new web component APIs must go through their own standards process.
A combination of various community groups and browser vendor teams are continuously working together to propose new APIs, specify and standarize how they should work, and then get them implemented across browsers.
This. process. takes. time.
Lucky for us, this process is starting to move quicker. Efforts like Interop 2022, Interop 2023, and Interop 2024 have meant all major browser vendors are working together to solve browser compatibility issues and is hinting at a new reality where these vendors are committing to be better about implementing new and existing APIs in a timely and consistent way.
Even with a quicker feedback loop, however, new web component features will (for the most part) always take longer to ship than new web framework features.
This can often be frustrating to some people, but there is an important tradeoff being made. The upfront cost of standards work means that any API added to browsers is committing to be backwards compatible. Once a web component API is added, it's here to stay.
The end result is that web components should outlast entire web frameworks.
What are web component frameworks and should I use them?
Web component frameworks are opinionated abstractions on top of the lower level browser APIs that have been mentioned above. They usually provide enhancements such as improved templating, reactive data, declarative syntax, and other general improvements to the experience of building web components.
You very likely want to use a web component framework when building web components.
As a jumping off point, some great web component frameworks, libraries, and compilers to check out are:
- Lit (by Google)
- FAST (by Microsoft)
- WebC (by Zach Leatherman, creator of 11ty)
- Stencil (by Ionic)
- Haunted (by Matthew Phillips, co-creator of Astro)
- Lume Element (by Joe Pea)
- Stellar (by Hawk Ticehurst, creator of this website!)
For an even more exhaustive list of web component frameworks/libraries check out this article.
It’s also worth noting that a number of more “traditional” web frameworks (such as Svelte, Solid, Preact, and Vue) have the ability to export their components as standalone web components.
I want to learn more, where do I go from here?
Great question! Below is a list of web component blog posts and resources that are worth reading. It’s organized in no particular order so feel free to skim and pick up one that looks interesting.
- JavaScript.info Web Component Articles by Ilya Kantor
- Debunking Web Component Myths and Misconceptions by Rob Eisenberg
- About Web Components by Rob Eisenberg
- Web Components Eliminate JavaScript Framework Lock-in by Jake Lazaroff
- Web Components Bookmarks by Serhii Kulykov
- HTML with Superpowers by Dave Rupert
- Awesome Standalone Web Components by Dave Rupert
- A Web Components Primer by Cory LaViska
- Using Web Components on My Icon Galleries Websites by Jim Nielsen
- How we use Web Components at GitHub by Kristján Oddsson
- An Interactive Introduction to Web Components by Hawk Ticehurst