@feugene/granularity

Granularity design system package with Vue 3 components, consumed via the `@feugene/granum` build pipeline.
21,214 1
Install
npm install @feugene/granularity
Latest Version:3.1.0
Vue:3
License:LicenseRef-Granularity-EUC-1.1
Last Updated:Oct 21, 2026
Links: GitHub  ·  npm
Maintainer: efureev

@feugene/granularity

@feugene/granularity is a Vue 3 design system package that helps you build interfaces faster, cleaner, and more predictably: with ready-made components, a transparent styling system, granular imports, and a build pipeline that ships a machine-generated manifest instead of setup instructions.

It's built for cases where a design system needs to be more than just a set of UI pieces — a working engineering tool: convenient for a product team, scalable for a large application, and flexible enough for different adoption strategies.

Why it exists

  • to launch new screens and features on a single visual foundation;
  • to adopt the package incrementally, without rewriting the whole application;
  • to control the size of the JS and CSS you ship, when that actually matters;
  • to use the same package both as a ready-made component library and as a source of low-level package-level APIs.

What makes granularity good

  • Fast start without unnecessary magic. You can simply import components and ready-made style entrypoints.
  • Granular imports. Every component is its own subpath export, so the bundle carries exactly what you import and nothing next to it.
  • Sane styling. Tokens, base styles, themes, and component-level CSS are split into clear layers.
  • Ready for real scale. The package works for "just plugged in a few components" as well as scenarios where dependency-aware imports, safelist, and precise CSS pipeline tuning matter.
  • One plugin, no scanning. The package ships granum.manifest.json: classes, consumed tokens, dependencies, theme files and component CSS are computed when the package is built, so the application reads them instead of scanning node_modules.
  • Not just components. Alongside the UI you get directives, a file validation API, and utility entrypoints for infrastructure scenarios.

Technical highlights

  • root export: @feugene/granularity — plugins, composables, utilities, constants and types. Components come from their subpaths: with granum, a component imported from the root is a ComponentRootImportError, because the selection only sees a component by its subpath and the root loads the whole package;
  • component subpath exports: @feugene/granularity/components/<ComponentName>;
  • ready-made CSS entrypoint: @feugene/granularity/styles.css — the slate theme in both modes (light, dark) with the core component tokens and the base layer in one file, for consumers who do not run the build pipeline. A mode is switched by the pair data-theme="slate-dark". A component's own CSS is not there: with granum it arrives through the manifest;
  • low-level foundation exports: a ready theme of the catalog by parts — @feugene/granularity/themes/<theme>/root.css plus themes/<theme>/<mode>.css for the modes you need — or whole, themes/<theme>.css; @feugene/granularity/styles/base.css, @feugene/granularity/styles/preflight.css;
  • package-level API: @feugene/granularity/directives, @feugene/granularity/fileValidation;
  • design tokens as data: the registry of component tokens at @feugene/granularity/tokens; global tokens, theme data and the theme builder live in @feugene/granularity-tokens, a dependency of this package;
  • build manifest: @feugene/granularity/granum.manifest.json — what the application's granum() plugin reads; it also records the utility vocabulary the classes belong to in its engine block. The provider registry itself stays available as @feugene/granularity/granular-provider for packages that extend it.

Limitations

RTL is not supported. Components lay themselves out with physical directions (pl-/pr-, ml-/mr-, left-/right-), and dir="rtl" is not read anywhere: a right-to-left document will render mirrored padding, offsets and floating panels. This is a deliberate decision for the 1.x line — moving to logical properties changes how every component looks, which is a visual breaking change and belongs in a major release, not a patch. See docs/styling.md.

Quick start

yarn add @feugene/granularity vue @floating-ui/dom

@floating-ui/dom is a required peer dependency, not a bundled one: positioning (GrDropdown, GrSelect, GrAutocomplete, GrTreeSelect, GrTooltip) is built on it, and keeping it external means an application that already uses floating-ui ends up with a single copy.

The overlay components (GrModal, GrDrawer, GrDialog, GrImageViewer) need nothing else — their focus trap, layer stack and scroll lock are the package's own primitives. @headlessui/vue was dropped in 0.15.0 and is not a peer dependency; if it is still installed for this package alone, it can be removed.

The supported setup is the granum plugin:

yarn add -D @feugene/granum @feugene/granum-engine-wind

Two packages, not one: granum is the pipeline and ships no utility engine of its own, so the application picks the vocabulary and hands over an instance. @feugene/granum-engine-wind is the default implementation — preset-wind3 plus the extra rule the components are drawn with.

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

export default defineGranumConfig({
  engine: windEngine(),
  providers: ['@feugene/granularity'],
  appSources: { dirs: ['src'] },
})

The package declares the vocabulary its classes are written against — unocss/preset-wind3+granum@66. An engine with a different dialect makes granum report provider-dialect-mismatch and name every class it had to drop, instead of letting components render half-styled. See docs/granum.md.

// src/main.ts
import 'virtual:granum.css'

That single module carries five cascade layers: tokens, base, themes, the CSS of the components you selected, and the utility classes they are built from.

Components are imported from their subpaths:

<script setup lang="ts">
import { GrButton } from '@feugene/granularity/components/GrButton'
</script>

<template>
  <GrButton>Save</GrButton>
</template>

Without the plugin there is still a static fallback — @feugene/granularity/styles.css — with tokens, the base layer, the preflight and the built-in light/dark themes. What it does not carry is the utility classes, so components render with their own CSS but without layout.

Granular imports, in numbers

What you import gzip of the barrel
the whole package from the root 665.9 kB 100 %
the lightest component — GrSkeleton 1.7 kB < 1 %
the median component — GrSegmented 21.5 kB 3 %
the 5 heaviest together 261.3 kB 39 %

These numbers do not add up: shared code is counted again in every row but paid for once, which is why the set is shown as a union rather than a sum. They are an upper bound — the gzip of everything a subpath pulls out of dist, before the application bundler shakes it further and minifies it again.

The weight of every component — docs/entry-sizes.md.

The rest of the family

The core ships the general-purpose components. Anything that carries a heavy dependency, belongs to a domain of its own, or is needed by a minority of consumers lives in a companion package with a peer on this one — the core stays lean, and you install only what you reach for.

Package Version What it adds
@feugene/granularity-charts 2.0.2 Charts — own SVG, zero dependencies, drawn with theme tokens.
@feugene/granularity-chrono 2.0.2 Calendar, date and time components — no third-party date widget, no date library.
@feugene/granularity-code 2.0.2 Code surfaces: view, edit and diff — the viewer and the diff carry no dependencies at all.
@feugene/granularity-dashboard 2.0.2 Widget grid — drag, resize, breakpoints and layout persistence, zero dependencies.
@feugene/granularity-datasource 0.1.2 List state: sorting, filters, paging, URL sync and race-free fetching behind one composable.
@feugene/granularity-devtools 2.1.1 Vue DevTools panel — where a prop value came from, the overlay layer stack and design-system warnings.
@feugene/granularity-editor 2.0.2 Rich-text editing: a TipTap-backed GrRichText field with a design-system toolbar.
@feugene/granularity-forms-schema 2.0.2 Schema-driven forms — zod and JSON Schema into real form fields, zero dependencies.
@feugene/granularity-media 2.0.2 Media components: image cropping, camera capture, code scanning and video playback.
@feugene/granularity-test-kit 2.2.0 Test gates for @feugene/granularity design-system packages — token, registry and defaults contracts as reusable factories.
@feugene/granularity-tokens 2.1.0 Design tokens and themes of @feugene/granularity: the token registry, theme data by mode and the theme builder.
@feugene/unplugin-granularity 1.2.1 unplugin-vue-components resolver — granular auto-import for components and directives.

Documentation

Related Packages

@cuboapp/ui-vue

Vue 3 flavour of the Cubo UI kit — components built on @cuboapp/styles design to...

19,742
@63pokupki/design-system

UI component kit and design-system for 63 Pokupki project

32,580 5
futility-ui

A set of ready-to-use UI components for Vue 3, styled according to the Flowbite...

4,934 1
works-ui

Simple Vue 3 UI library

1,480 0

Version History

Version Released License
3.1.0 LicenseRef-Granularity-EUC-1.1
3.0.0 LicenseRef-Granularity-EUC-1.1
2.4.0 LicenseRef-Granularity-EUC-1.1
2.3.0 LicenseRef-Granularity-EUC-1.1
2.2.0 LicenseRef-Granularity-EUC-1.1