@feugene/granularity

中文文档
3.7.2发布于 2026/10/29LicenseRef-Granularity-EUC-1.1TypeScriptES Module构建来源已验证近 30 天下载 4932

Granularity design system package with Vue 3 components, consumed via the @feugene/granum build pipeline.

原始使用文档
文档目录8 节
  1. Why it exists
  2. What makes granularity good
  3. Technical highlights
  4. Limitations
  5. Quick start
  6. Granular imports, in numbers
  7. The rest of the family
  8. Documentation

@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: every floating panel — selects, menus, tooltips, popovers — is positioned with it, and so is everything that renders one (the data table, pagination, the sidebar, the colour picker); an import from the package root always pulls it in. Without it the application's build fails to resolve the import from dist/composables/useFloating.js. 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 importgzipof the barrel
the whole package from the root646.5 kB100 %
the lightest component — GrSkeleton1.7 kB< 1 %
the median component — GrTextarea19.5 kB3 %
the 5 heaviest together251.8 kB39 %

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.

PackageVersionWhat it adds
@feugene/granularity-charts4.0.0Charts — own SVG, zero dependencies, drawn with theme tokens.
@feugene/granularity-chrono4.0.1Calendar, date and time components — no third-party date widget, no date library.
@feugene/granularity-code4.0.1Code surfaces: view, edit and diff — the viewer and the diff carry no dependencies at all.
@feugene/granularity-dashboard3.0.1Widget grid — drag, resize, breakpoints and layout persistence, zero dependencies.
@feugene/granularity-datasource0.1.2List state: sorting, filters, paging, URL sync and race-free fetching behind one composable.
@feugene/granularity-devtools2.1.1Vue DevTools panel — where a prop value came from, the overlay layer stack and design-system warnings.
@feugene/granularity-editor4.0.1Rich-text editing: a TipTap-backed GrRichText field with a design-system toolbar.
@feugene/granularity-forms-schema3.0.1Schema-driven forms — zod and JSON Schema into real form fields, zero dependencies.
@feugene/granularity-media4.0.0Media components: image cropping, camera capture, code scanning and video playback.
@feugene/granularity-test-kit2.4.0Test gates for @feugene/granularity design-system packages — token, registry and defaults contracts as reusable factories.
@feugene/granularity-tokens2.5.0Design tokens and themes of @feugene/granularity: the token registry, theme data by mode and the theme builder.
@feugene/unplugin-granularity1.2.1unplugin-vue-components resolver — granular auto-import for components and directives.

Documentation

版本与发布记录

@feugene/granularity 共发布 117 个版本,首次发布于 2026/04/17;过去 12 个月发布了 117 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
3.7.2latest2026/10/2916 天前
3.7.12026/10/2916 天前
3.7.02026/10/2817 天前
3.6.02026/10/2817 天前
3.5.02026/10/2817 天前
3.4.12026/10/2817 天前

关于 @feugene/granularity 的常见问题

@feugene/granularity 是什么?

Granularity design system package with Vue 3 components, consumed via the @feugene/granum build pipeline.

如何安装 @feugene/granularity?

在项目目录运行 npm install @feugene/granularity,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:vue(^3.5.0)、@feugene/granum(>=3.10.0 <4.0.0)、@floating-ui/dom(^1.8.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@feugene/granularity 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@feugene/granularity 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@feugene/granularity 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@feugene/granularity 可以商用吗?

@feugene/granularity 使用 LicenseRef-Granularity-EUC-1.1 许可。声明的许可为 LicenseRef-Granularity-EUC-1.1,请阅读许可原文确认使用条件。以上为概括,不构成法律意见,请以许可原文为准。

@feugene/granularity 的下载量有多少?

根据 npm 官方下载统计,@feugene/granularity 在 2026/10/15 – 2026/11/13 这 30 天内被下载 4,932 次,日均约 164 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@feugene/granularity 还在维护吗?

最新版本 3.7.2 发布于 2026/10/29(16 天前);至今共发布 117 个版本,其中过去 12 个月发布了 117 个;首次发布于 2026/04/17。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。