Введение

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

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

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

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

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

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

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

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

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

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

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

uno.config.ts
import granularityProvider from '@feugene/granularity/granular-provider/node'
import { granularContent, presetGranularNode } from '@feugene/unocss-preset-granular/node'

// Оба вызова берут один и тот же объект опций. Дадите им разойтись —
// компоненты приедут без стилей.
const options = {
  providers: [granularityProvider],
  components: [{ provider: '@feugene/granularity', names: ['GrButton', 'GrCard'] }],
  themes: { names: ['light', 'dark'] },
}

Куда дальше

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

Последняя ревизия: 2026-08-29