Відзначимо: коли 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+ років. Отримайте консультацію з архітектури. Зв'яжіться з нами для оцінки вашого проєкту.







