Відзначимо: коли React, Vue та Angular вимагають кожен своєї UI-бібліотеки, код дублюється — команди витрачають до 30% часу на переписування одних і тих же кнопок і модалок. Ми вирішили цю проблему за допомогою Stencil: компілятора, який з одного TypeScript-коду генерує нативні Web Components та обгортки для всіх популярних фреймворків. З 2019 року ми створили понад 40 UI-бібліотек, включаючи проєкт для фінтех-застосунку на 15+ компонентів — він використовується в React, Vue та Angular без доопрацювань, скоротивши час імплементації нових фіч на 40%. Інший приклад: для e-commerce платформи зібрали UI-kit з 25 компонентів. Після впровадження в три сервіси команда вдвічі скоротила час на узгодження інтерфейсів. Кожен компонент покритий юніт- та E2E-тестами (40+ тестів на компонент), що виключає баги при інтеграції. Наші клієнти економлять від 30% бюджету на UI-розробку та отримують стабільну бібліотеку на весь життєвий цикл застосунку. Ми сертифіковані партнери Ionic, гарантуємо якість та 6 місяців підтримки.
Проблеми, які вирішуємо
Фрагментація коду
Без єдиної бібліотеки кожен проєкт пише свої кнопки, інпути та модалки. Результат — роздутий код, різні UX, складна підтримка. За нашими даними, компанії витрачають до 30% часу розробки на дублювання UI-компонентів, що призводить до перевитрати бюджету на 20–30%. Ми пропонуємо єдиний source of truth.
Складність інтеграції
Нативні Web Components не завжди коректно працюють з React (bubbling подій, типи пропсів) або Angular (двосторонній біндінг, форми). Stencil генерує framework-специфічні обгортки, які вирішують ці проблеми. Розробникам не потрібно писати адаптери вручну — це економить до 2 тижнів на початкову інтеграцію та знижує ризики помилок.
Продуктивність
Stencil компілює компоненти в нативні Custom Elements з мінімальним оверхедом. На відміну від Lit, він додатково створює tree-shakeable збірки та може працювати з SSR. На тестах bundle size зменшується на 60% порівняно з традиційними фреймворк-бібліотеками. Stencil краще Lit в 2-3 рази для генерації обгорток.
Як ми це робимо: занурення в Stencil
Архітектура проєкту
Починаємо з ініціалізації Stencil-проєкту. Типова структура:
npm init stencil@latest -- --type component cd my-library && npm install Проєкт організовуємо в монорепозиторій з пакетами для кожного фреймворку.
Компонент: приклад ui-button
Створюємо компонент за допомогою декораторів @Component, @Prop, @Event. Він використовує TSX, як у React. Важливо: включення Shadow DOM (shadow: true) для ізоляції стилів.
// ui-button.tsx import { Component, h, Prop, Event, EventEmitter } from '@stencil/core'; @Component({ tag: 'ui-button', styleUrl: 'ui-button.css', shadow: true, }) export class UiButton { @Prop() variant: 'primary' | 'secondary' = 'primary'; @Prop() disabled = false; @Event() uiClick!: EventEmitter<MouseEvent>; render() { return ( <button class={`btn btn--${this.variant}`} disabled={this.disabled} onClick={e => this.uiClick.emit(e)} > <slot /> </button> ); } } Конфігурація: кілька output-таргетів
Головна фіча інструмента — один код, багато збірок. Налаштовуємо stencil.config.ts для генерації:
- Нативних Web Components (dist)
- Дерево-шейканих custom elements (dist-custom-elements)
- React-обгорток
- Vue-обгорток
- Angular-обгорток
// stencil.config.ts import { Config } from '@stencil/core'; import { reactOutputTarget } from '@stencil/react-output-target'; import { vueOutputTarget } from '@stencil/vue-output-target'; import { angularOutputTarget } from '@stencil/angular-output-target'; export const config: Config = { outputTargets: [ { type: 'dist', esmLoaderPath: '../loader' }, { type: 'dist-custom-elements' }, reactOutputTarget({ componentCorePackage: 'core', proxiesFile: '../react/src/components.ts' }), vueOutputTarget({ componentCorePackage: 'core', proxiesFile: '../vue/src/components.ts' }), angularOutputTarget({ componentCorePackage: 'core', directivesProxyFile: '../angular/src/proxies.ts' }), { type: 'docs-readme' }, ], }; Після збірки в кожному фреймворк-пакеті з'являються готові типізовані компоненти. Їх можна імпортувати як звичайні. Бібліотека працює в React, Vue, Angular і навіть у чистому HTML — без додаткового налаштування.
Процес роботи
- Аналіз — визначаємо набір компонентів, дизайн-токени, вимоги до a11y.
- Проєктування — розробляємо архітектуру компонентів, пропси, події.
- Реалізація — пишемо компоненти на Stencil, стилізуємо, додаємо тести (Jest + Puppeteer).
- Інтеграція — генеруємо обгортки для цільових фреймворків, перевіряємо в їхньому оточенні.
- Документація — створюємо Storybook та автоматичну документацію з Stencil.
- Публікація — налаштовуємо CI/CD на GitHub Actions, публікуємо npm-пакети.
Що входить в роботу
- Вихідний код компонентів на Stencil (TypeScript, CSS)
- Збірки для React, Vue, Angular (якщо потрібно)
- Модульні та E2E-тести (Jest + Puppeteer) — понад 800 тестів на бібліотеку
- Документація (README, Storybook, JSDoc)
- Конфігурація CI/CD (GitHub Actions, публікація в npm)
- 2 тижні безкоштовної підтримки після завершення, далі — гарантія 6 місяців
Строки та вартість
| Обсяг бібліотеки | Строк | Вартість (USD) |
|---|---|---|
| 5–8 компонентів (тільки React) | 2–3 тижні | від $2000 |
| 10–20 компонентів (React + Vue + Angular) | 6–8 тижнів | від $8000 |
| Повний UI-kit (30+ компонентів) | 8–12 тижнів | від $15 000 |
Вартість розраховується індивідуально — залежить від складності компонентів, кількості фреймворків та необхідності тестування. Економія бюджету до 40% порівняно з окремою розробкою для кожного фреймворку.
Чому Stencil краще Lit для корпоративних бібліотек?
Stencil надає готові output-таргети для популярних фреймворків. Це скорочує час інтеграції в 2-3 рази. Крім того, він генерує документацію та TypeScript-типи автоматично. Наш досвід показує: проєкти на Stencil вимагають на 40% менше часу на підтримку крос-фреймворкової сумісності.
Як Stencil вирішує проблему гідратації в React?
При використанні нативних Web Components в React виникають помилки гідратації через невідповідність серверного та клієнтського рендеру. Stencil генерує React-обгортки, які коректно обробляють події та атрибути, усуваючи гідратацію.
Приклад використання в React
import { UiButton } from 'my-ui-react'; function App() { return <UiButton variant="primary" onUiClick={e => console.log(e.detail)}>Click me</UiButton>; } Порівняння Stencil та Lit
| Параметр | Stencil | Lit |
|---|---|---|
| Генерація обгорток для фреймворків | Вбудована (React, Vue, Angular) | Потребує ручної реалізації |
| Типізація пропсів | Автоматична з TSX | Ручна через дженерики |
| Tree-shaking | Так (dist-custom-elements) | Частково |
| Документація | Автогенерація з компонентів | Окремий інструмент |
| Час інтеграції | 2-3 дні | 1-2 тижні |
Замовте розробку бібліотеки під ключ від сертифікованих спеціалістів з досвідом 5+ років. Отримайте консультацію з архітектури. Зв'яжіться з нами для оцінки вашого проєкту.







