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.

React is the one notable exception in 2024. Native support for web components is available in the current @beta release, but has not yet been formally released in a stable version. Despite this, there are still ways to use web components in older versions of React.

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.

If you would like to build your web components with some of these ergonomic improvements you’ll want to look into web component frameworks/compilers (discussed below).

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.

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:

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>

For even more information and discussion on what web components can look like, Jim Nielsen has written some great articles on the topic.

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:

There is also a lifecycle method for when a component attribute has been changed, added, removed, or replaced.

It's also worth mentioning the Shadow DOM API and HTML <template> element, which are commonly used when authoring web components.

The Shadow DOM API is a JavaScript API that is primarily used for creating scoped styles and component slots, while the <template> element is used to define and store the markup of a web component.

These and other web component APIs are discussed more below.

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.

If you want to dive deeper here are some great posts that talk more about HTML Web Components and some of the differences they have with JavaScript Web Components.

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.

Historical context: This is the reason that web components, despite being introduced back in the early 2010s, have taken so long to really increase in adoption. It took almost a decade to get the first set of web component APIs standarized and implemented across all major browsers.

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:

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.