Введение

  • Начало работы
  • 2 мин
  • кода: 2

Что такое Granularity и какое одно решение задаёт в ней всё остальное.

Ревизия 2026-10-15

На этой странице

Granularity — дизайн-система для Vue 3: компоненты, основы и конвейер, который собирает из них CSS. Имя здесь не украшение, а описание того единственного решения, из которого следует всё остальное.

Выбор, а не дробление

Большинство библиотек компонентов дают гранулярность дроблением на подпакеты: ядро, потом формы, потом навигация. Эта отказывается, и причина измерима: большинство рёбер её графа зависимостей пересекают границы её же групп каталога — точная доля считается на каждой сборке, потому что она меняется вместе с библиотекой. GrDrawer рендерит GrButton. GrPagination рендерит GrSelect. GrDataTable рендерит GrCheckbox. Разрежьте по этим группам — получите пакеты, зависящие друг от друга кольцом.

Группы каталога существуют для читателя, который ищет компонент под задачу. Они никогда не описывали, кто кого рендерит, и не описывают.

Поэтому гранулярность берётся с другого конца. Вы называете компоненты, которые рендерите; сборка разрешает их граф зависимостей и эмитит ровно тот CSS. Ядро — один пакет, одна версия, один changelog, и бандл растёт от того, что вы используете. Спутники вроде графиков и редактора живут отдельными пакетами со своими версиями, но ядро внутри не режется.

Чем именно платите

  1. Первый компонент несёт токены, базовый слой и темы, названные в themes.names.
  2. Каждый следующий добавляет от пары сотен байт до нескольких килобайт стилей — столько, сколько весит его собственный граф.
  3. В рантайме не подтягивается ничего: у ядра ноль runtime-зависимостей.

Числа за этими тремя строками сняты с настоящей сборки и стоят на главной — это именно они, а не округление.

npm i @feugene/granularity
pnpm add @feugene/granularity
yarn add @feugene/granularity
bun add @feugene/granularity

Плюс конвейер на сборку — @feugene/granum и @feugene/granum-engine-wind; полный состав — в быстром старте.

Выбор компонентов

granum.config.mjs
import { windEngine } from '@feugene/granum-engine-wind'
import { defineGranumConfig } from '@feugene/granum/vite'

export default defineGranumConfig({
  engine: windEngine(),
  providers: ['@feugene/granularity'],
  components: [{ provider: '@feugene/granularity', names: ['GrButton', 'GrCard'] }],
  themes: { names: ['light', 'dark'] },
})

Куда дальше

Если нужно запустить — быстрый старт самая короткая полезная страница сайта. Если хочется сначала понять, почему экспорты устроены так, читайте архитектуру.