Web Components as a Business Decision
Most framework decisions are really hiring decisions, maintenance decisions, and migration risk decisions wearing a technical costume. Web Components are worth understanding not because they're "pure" or "native" -- but because they solve specific business problems that framework-heavy stacks create.
The business case
When you pick React, Vue, or Svelte for a project, you're also picking:
- A hiring pool. You need developers who know that framework, or are willing to learn it.
- A migration timeline. Frameworks ship breaking changes. React class components, Vue 2 to 3, Angular.js to Angular -- every major framework has forced expensive rewrites on teams that bet heavily.
- A bundle tax. Frameworks add 30-200KB of runtime JavaScript before your first line of business logic runs. For content sites and lightweight tools, that's paying rent on a warehouse when you need a closet.
Web Components don't eliminate these concerns, but they change the math. They're a browser standard. They don't ship breaking versions. They work alongside any framework or no framework. And they add zero runtime overhead because the browser already knows how to run them.
What Web Components actually are
Three browser APIs working together:
- Custom Elements -- define new HTML tags with your own behavior.
- Shadow DOM -- encapsulate styles and markup so components don't leak CSS into (or absorb CSS from) the rest of the page.
- HTML Templates -- define reusable markup structures.
A minimal example
class StatusBadge extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({mode: 'open'});
shadow.innerHTML = `
<style>
span { padding: 2px 8px; border-radius: 4px; font-size: 0.85em; }
:host([status="active"]) span { background: #e6f4ea; color: #1e7e34; }
:host([status="inactive"]) span { background: #fce8e6; color: #c62828; }
</style>
<span><slot></slot></span>
`;
}
}
customElements.define('status-badge', StatusBadge);
Usage:
<status-badge status="active">Live</status-badge>
<status-badge status="inactive">Offline</status-badge>
No build step. No imports. No package.json entry. It just works in every modern browser.
When Web Components make sense
Web Components are a strong fit when:
- You're a small team shipping fast. Less tooling means less time spent on configuration and more time spent on product. I use them throughout this site's architecture for exactly this reason.
- You need components that survive framework changes. If you're building a design system that might outlive your current stack, Web Components are the safest long-term bet.
- You want progressive enhancement. The page works without JavaScript; components enhance it when JS is available. This pairs naturally with HTMX-based progressive enhancement.
- Bundle size is a competitive advantage. Faster pages rank better, convert better, and cost less to serve. The HAL performance case study shows what this looks like in practice.
When they don't
Be honest about the tradeoffs:
- Complex state management. If your app has deeply nested shared state, a framework with built-in reactivity (React, Vue, Svelte) will save you time. Web Components don't have a built-in state solution.
- Large team coordination. Frameworks provide conventions. Those conventions are valuable when you have 20 developers who need to write consistent code. Web Components give you less guardrails.
- Rich ecosystem needs. If you need a component library with 50+ pre-built widgets, framework ecosystems are further ahead.
Getting started
- Create a class that extends
HTMLElement. - Attach a Shadow DOM in the constructor for style encapsulation.
- Register it with
customElements.define('your-tag', YourClass). - Use it in HTML like any other element.
No build step, no CLI, no starter template. That's not a flex -- it's a genuine reduction in startup cost and ongoing maintenance burden.
The bottom line
Web Components aren't a religion. They're a tool with specific strengths: zero runtime cost, no framework lock-in, excellent browser support, and a standard that won't ship breaking changes. For content sites, internal tools, and design systems that need to last, those properties translate directly into lower cost and lower risk. For complex applications with heavy state management, a framework is probably the right call.
Pick the tool that fits the problem. Ship the thing.