Web Components появились в браузерах в 2011 году — Google предложил стандарт, и все сказали «это будущее». Прошло 15 лет. React захватил рынок, Vue вырос из ниоткуда, Svelte добавил интриги. А Web Components всё ещё «будущее».
Что с ними не так? Или всё-таки так?
Что это вообще такое
Web Components — не библиотека и не фреймворк. Это набор нативных браузерных API, которые позволяют создавать собственные HTML-элементы. Буквально: вы пишете <my-button> и браузер понимает, что с этим делать.
Стандарт держится на трёх китах:
Custom Elements — регистрируете новый тег. customElements.define('my-button', MyButtonClass) — и теперь <my-button> полноценный элемент со своим поведением.
Shadow DOM — изолированное DOM-дерево внутри элемента. CSS снаружи не проникает внутрь, стили компонента не текут наружу. Никакого конфликта классов.
HTML Templates — тег <template>, содержимое которого не рендерится до момента, пока вы его явно не вставите в документ. Удобно для переиспользуемых кусков разметки.
Всё это — часть HTML-спецификации. Без npm, без webpack, без babel.
Почему они не взлетели массово
Если Web Components — нативный стандарт, почему все пишут на React?
Первая причина: время. Custom Elements v1 (нормальная версия) приехала в Chrome в 2016, в Firefox — в 2019. Safari долго упирался. Экосистема React к тому моменту уже работала везде через полифиллы. Пока стандарт согласовывался комитетами, React строил сообщество.
Вторая причина: DX. Написать компонент на чистых Web Components — значит писать больше кода, чем в любом фреймворке. Вот простейший счётчик:
class MyCounter extends HTMLElement {
constructor() {
super();
this._count = 0;
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
this.render();
this.shadowRoot.querySelector('button').addEventListener('click', () => {
this._count++;
this.render();
});
}
render() {
this.shadowRoot.innerHTML = `
<style>button { color: blue; }</style>
<p>Count: ${this._count}</p>
<button>+1</button>
`;
}
}
customElements.define('my-counter', MyCounter);
В React то же самое — 5 строк. Здесь — 25, и это без нормальной реактивности, без state management, без шаблонизатора. Перерисовывать innerHTML целиком при каждом изменении — варварство.
Третья причина: реактивность нужно делать самому. Web Components не следят за данными. Изменили переменную — DOM сам не обновится. Нужно либо писать свой микро-фреймворк, либо подключать библиотеку.
Где они реально работают
При всём этом Web Components живут, причём в очень серьёзных местах.
GitHub использует их для большей части интерфейса. Теги <relative-time>, <details-dialog>, <include-fragment> — их собственные компоненты, открытый исходный код.
Adobe Spectrum — дизайн-система Adobe — построена целиком на Web Components. Это позволяет использовать компоненты в любом фреймворке: в React, Vue, Angular и в чистом HTML.
Salesforce Lightning — весь UI Salesforce. Миллионы пользователей ежедневно.
YouTube частично перешёл на Polymer — надстройку над Web Components от Google.
Видите закономерность? Это крупные компании с большими командами, которым нужна фреймворк-независимость. Они не могут позволить себе привязаться к React — завтра выйдет React 5 с breaking changes, и переписывать UI на 200 компонентов никто не хочет.
Shadow DOM — главная суперсила
Из трёх API самый интересный — Shadow DOM. Именно он делает компоненты по-настоящему изолированными.
Когда создаёте Shadow DOM, браузер строит отдельное дерево, скрытое от внешнего документа. Стили снаружи туда не попадают. Ваши стили не вытекают наружу. JavaScript-запросы вроде document.querySelector не видят, что внутри.
Это решает боль, знакомую каждому фронтендеру: подключаешь чужой виджет, он ломает вёрстку — потому что использует классы .button, .title, .wrapper, которые пересекаются с вашими.
С Shadow DOM такого не будет. Виджет живёт в своей капсуле.
Обратная сторона: глобальные стили (CSS Variables и часть cascade) всё равно проникают внутрь. Это фича, а не баг — позволяет передавать тему через переменные. Но поначалу кажется нелогичным и сбивает с толку.
Lit — главный инструмент для Web Components
Писать на голых Web Components неудобно. Поэтому Google разработал Lit (раньше Polymer и LitElement).
Lit — минималистичная библиотека (~5 КБ gzip), которая добавляет реактивные свойства, шаблонизатор на tagged template literals и декораторы. Тот же счётчик на Lit:
import { LitElement, html } from 'lit';
import { customElement, property } from 'lit/decorators.js';
@customElement('my-counter')
class MyCounter extends LitElement {
@property({ type: Number }) count = 0;
render() {
return html`
<p>Count: ${this.count}</p>
<button @click=${() => this.count++}>+1</button>
`;
}
}
Уже нормально. И это компилируется в нативный Web Component — без рантайма React, без Virtual DOM.
Есть и другие инструменты: Stencil (используется Ionic), Haunted (хуки для Web Components), FAST от Microsoft — используется в Fluent UI.
Интеграция с React и Vue
Один из главных аргументов в пользу Web Components — они работают в любом окружении. Но с React исторически был нюанс.
React до версии 19 плохо дружил с Custom Elements. Передать объект или массив через атрибут было неудобно — React конвертировал всё в строки. Обработка кастомных событий тоже отличалась от обычных.
С React 19 это починили: теперь React нормально работает с Custom Elements — передаёт свойства напрямую, слушает кастомные события без обёрток.
Vue и Angular всегда поддерживали Web Components лучше. Angular вообще умеет компилировать свои компоненты в Web Components через @angular/elements — удобно, если нужно переиспользовать что-то вне Angular-проекта.
Когда стоит использовать
Дизайн-системы для больших команд — идеальный кейс. Если у вас несколько продуктов на разных фреймворках, Web Components позволяют один раз написать компонент кнопки, модалки, таблицы и использовать везде без адаптации.
Виджеты для встраивания — чат-боты, формы обратной связи, кнопки отзывов. Клиенту нужно вставить один тег — всё работает без конфликтов со стилями сайта. Именно так в REEXY делают встраиваемые виджеты для клиентов: Shadow DOM гарантирует, что компонент не сломает чужую вёрстку независимо от того, на чём сделан сайт.
Микрофронтенды — когда разные команды пишут разные части одного интерфейса на разных технологиях. Web Components позволяют изолировать части друг от друга.
Долгосрочные проекты — если уверены, что проект живёт 10+ лет, нативный стандарт надёжнее, чем фреймворк. HTML-спецификация обратно совместима; React 5.0 может принести breaking changes.
Когда не стоит
Обычный сайт или лендинг — избыточно. Корпоративный сайт или лендинг — не тот масштаб, при котором выгоды Web Components перекрывают порог вхождения.
Команда не знакома со стандартом — кривая обучения есть. Разработчики, которые всю жизнь писали на React, поначалу будут работать медленнее и совершать неочевидные ошибки с Shadow DOM.
Нужна быстрая разработка — экосистема React богаче на порядок. Готовых компонентов, документации, решений для типичных задач несравнимо больше.
Сложный state management — Zustand, Redux, TanStack Query — у фреймворков куда богаче инструменты для управления состоянием. В мире Web Components это нужно собирать из отдельных библиотек.
Поддержка браузеров в 2026
Custom Elements v1 поддерживают все современные браузеры: Chrome 67+, Firefox 63+, Safari 12.1+, Edge 79+. Полифиллы нужны только для IE11 — но это уже музейный экспонат.
Одна проблема осталась: декларативный Shadow DOM (DSR). Это возможность задать Shadow DOM прямо в HTML без JavaScript — нужно для SSR. Chrome поддерживает, Firefox добавил в версии 123, Safari — в 17.4. Почти полное покрытие, но «почти» — слово, которое всё портит при работе с edge cases на продакшне.
Производительность
Нативные API быстрее, чем библиотеки поверх них — в теории. На практике всё зависит от того, как пишете.
Lit показывает хорошие результаты в бенчмарках: обновление DOM быстрее, чем у React с Virtual DOM, в простых сценариях. Но React с Concurrent Mode умеет делать сложные приложения очень отзывчивыми.
Для виджетов и встраиваемых компонентов — Web Components выигрывают однозначно. Не нужно тащить рантайм React весом 40+ КБ для кнопки с анимацией загрузки.
Стандарт или ниша
Честный ответ: и то, и другое.
Web Components — стандарт в том смысле, что это часть HTML-спецификации. Браузеры поддерживают их нативно, и это не исчезнет. GitHub, Adobe, Salesforce, Microsoft — достаточно серьёзные имена, чтобы технологию не хоронить.
Но это нишевая технология в том смысле, что для большинства задач — обычных сайтов, интернет-магазинов, стартапов — React или Vue дают более быструю разработку, богатую экосистему и больше готовых решений.
Область, где Web Components безусловно выигрывают: интероперабельность. Когда нужно написать один раз и использовать везде — в React-приложении, на WordPress-сайте, в Angular-проекте — альтернативы нет.
Для команды, которая строит дизайн-систему или встраиваемые виджеты, — это первый кандидат на рассмотрение. Для стартапа, которому нужно выкатить MVP за месяц, — React быстрее.
Следите за развитием декларативного Shadow DOM и инструментами вроде Lit. Если DSR получит полную поддержку во всех браузерах, а инструменты продолжат развиваться — Web Components займут гораздо более заметное место в типичном фронтенд-стеке. Пока — это мощный инструмент, который стоит знать и применять там, где он уместен.