Native web standards for creating reusable, encapsulated components that work in any framework or without one.
Web Components are a set of web standards enabling creation of custom, reusable HTML elements with style and behavior encapsulation. They work in any framework — or without one.
Web Components are based on three W3C/WHATWG specifications that work together:
connectedCallback, disconnectedCallback, attributeChangedCallback)<template> and <slot> elements for reusable declarative contentclass UserCard extends HTMLElement {
static observedAttributes = ["name", "role"];
constructor() {
super();
this.attachShadow({ mode: "open" });
}
connectedCallback() {
this.render();
}
attributeChangedCallback() {
this.render();
}
render() {
const name = this.getAttribute("name") ?? "Unknown";
const role = this.getAttribute("role") ?? "";
this.shadowRoot.innerHTML = `
<style>
:host {
display: block;
padding: 1rem;
border: 1px solid #333;
border-radius: 8px;
font-family: system-ui;
}
:host([highlighted]) { border-color: #58a6ff; }
.name { font-weight: 600; }
.role { color: #888; font-size: 0.875rem; }
</style>
<span class="name">${name}</span>
<span class="role">${role}</span>
`;
}
}
customElements.define("user-card", UserCard);Usage in HTML:
<user-card name="Ana García" role="Staff Engineer" highlighted></user-card>The :host selector styles the element itself. :host([highlighted]) responds to attributes. Styles inside the Shadow DOM don't affect the rest of the page and vice versa.
Lit simplifies authoring by eliminating the native API boilerplate:
import { LitElement, html, css } from "lit";
import { property } from "lit/decorators.js";
class UserCard extends LitElement {
static styles = css`
:host { display: block; padding: 1rem; border: 1px solid #333; border-radius: 8px; }
.name { font-weight: 600; }
.role { color: #888; font-size: 0.875rem; }
`;
@property() name = "";
@property() role = "";
render() {
return html`
<span class="name">${this.name}</span>
<span class="role">${this.role}</span>
`;
}
}
customElements.define("user-card", UserCard);Lit adds declarative reactivity, tagged template literal templates, and a typed property system — all in roughly 5 KB.
| Framework | Web Components usage | Limitations |
|---|---|---|
| React | Requires ref for complex properties; custom events need manual addEventListener | React 19 improves support with direct property passing |
| Vue | Native support with defineCustomElement; passes properties and listens to events without adapters | Minimal — Vue treats custom elements as first-class citizens |
| Angular | Full support with CUSTOM_ELEMENTS_SCHEMA; two-way binding works | Requires declaring the schema in the module |
| Svelte | Passes properties directly; listens to custom events with on: | No significant limitations |
The key distinction is that Web Components use HTML attributes (strings) and JavaScript properties (any type). Frameworks that distinguish between both — like Vue and Svelte — have better interoperability than those that treat everything as attributes.
| Framework | Author | Size | Focus |
|---|---|---|---|
| Lit | ~5 KB | Reactive, declarative, minimal boilerplate | |
| Stencil | Ionic | ~12 KB | Compiler that generates standard Web Components |
| FAST | Microsoft | ~8 KB | Adaptable design system, Fluent UI |
::part() to expose styling hooksWeb Components solve a problem that frameworks cannot: components that work in any context without runtime dependencies. For design systems that must serve teams using React, Vue, and Angular simultaneously, they are the only option that doesn't force a migration. The tradeoff is clear — more boilerplate and less ergonomics than a framework, but zero coupling and compatibility guaranteed by the browser.
Architectural pattern extending microservices to the frontend, allowing independent teams to develop and deploy parts of a web application autonomously.
Collection of reusable components, patterns, and guidelines ensuring visual and interaction consistency in digital products at scale.
JavaScript library for building user interfaces through declarative, reusable components, with an ecosystem spanning from SPAs to full-stack applications with Server Components.
Practice of designing and developing digital products usable by all people, including those with visual, auditory, motor, or cognitive disabilities.