跪拜 Guibai
← All articles
Frontend · JavaScript · Programmer

Web Components Still Can't Compete With Frameworks, and the Reason Isn't Technical

By ErpanOmer ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Web Components are often pitched as the future-proof, standards-based alternative to frameworks, but the gap between standards correctness and daily engineering usability means betting on them for a typical project adds cost and slows delivery with no offsetting benefit. The exception is a multi-framework enterprise design system, where framework-agnostic components genuinely reduce duplication.

Summary

Web Components ship with three W3C APIs—Custom Elements, Shadow DOM, and HTML Templates—and promise framework-agnostic reuse. But a simple counter component takes five times more code than React, requiring manual DOM string concatenation, event binding, and re-render triggers. No built-in reactivity means developers must hand-roll state-to-DOM synchronization, which turns complex forms into unmaintainable spaghetti. Shadow DOM's absolute style isolation breaks global theme overrides and utility-class workflows like Tailwind, while the absence of server-side rendering leaves components as empty shells until client JavaScript executes—a non-starter for SEO-sensitive projects. The cross-framework reuse pitch solves a problem most teams don't have, since organizations standardize on a single framework. The one defensible use case is a large enterprise with dozens of teams on different stacks needing a shared design system, which is why GitHub, Adobe, and SAP built theirs on Web Components. For the other 99% of teams, React or Vue remains the cheaper, faster choice.

Takeaways
A counter component takes 3 lines in React and over 15 lines in native Web Components, with manual HTML string building, event binding, and re-render calls.
The Web Components standard includes no reactivity system; state changes require hand-written attributeChangedCallback logic and manual DOM updates.
Shadow DOM's absolute CSS isolation prevents global theme variables and Tailwind utility classes from working unless the component author explicitly exposes every style property.
Server-side rendering is effectively unsupported because customElements.define doesn't exist in Node.js, leaving components as empty tags until client JS loads.
Cross-framework reuse is a pseudo-requirement for most teams, which standardize on a single framework across all projects.
Lit adds reactivity to Web Components but reintroduces framework dependency, undercutting the 'native standard' argument.
GitHub Primer, Adobe Spectrum, and SAP UI5 use Web Components for multi-framework design systems—the only scenario where the trade-offs pay off.
Conclusions

The core tension isn't Web Components versus React; it's that a standard designed by committee optimized for theoretical correctness while frameworks optimized for the developer's clock. Standards bodies can mandate APIs but can't mandate ergonomics.

Lit's existence as the de facto fix for Web Components' missing reactivity is a paradox: if you need a framework to make a standard usable, the standard hasn't actually eliminated the need for a framework.

The cross-framework reuse pitch targets a problem that exists mainly in conference talks, not in team org charts. Most companies enforce stack consistency precisely to avoid the integration pain Web Components claim to solve.

Concepts & terms
Custom Elements
A browser API that lets developers define new HTML tags with custom behavior by extending HTMLElement. Registration happens via customElements.define(), but the API only runs in browser JavaScript engines, not in Node.js.
Shadow DOM
An encapsulation mechanism that attaches a separate DOM tree to an element, isolating its CSS and JavaScript from the rest of the page. Styles inside cannot leak out, and external styles cannot penetrate in—except via CSS custom properties that the component author must explicitly expose.
HTML Templates
The <template> element holds inert HTML fragments that aren't rendered until cloned via JavaScript. Web Components use templates to define reusable markup structures.
attributeChangedCallback
A lifecycle callback in Custom Elements that fires when an observed attribute changes. It is the only built-in mechanism for reacting to property changes, and developers must manually implement DOM updates inside it.
From the discussion
Featured comments
贾东雷

Big companies are also pseudo-requirements. It's simply impossible for different teams to use the same component library. The communication cost is too high. Take Ant Design as an example. It's supposed to be usable across different teams, right? It's completely useless. If it's business components, the scenarios are even fewer. Different teams basically maintain their own business components.

ErpanOmer

Yes, that situation does happen.

See top comments, translated →
Source: juejin.cn ↗ Google Translate ↗ Backup ↗