Architecture

One package, granular by subpath rather than by sub-package, plus companions for anything heavy. This page shows why the split runs where it does — and recomputes the numbers behind that decision on every build.

77
core components
136
export paths
0
runtime dependencies in the core
12
packages in the family

Why the catalogue groups are not package boundaries

The catalogue splits components into groups — actions, forms, data, navigation — and those groups look like ready-made packages. They are not: the groups answer «where do I look for a component», while the dependency graph answers «who renders whom», and the two do not coincide.

78
edges in the render graph
56 (72%)
of them cross group boundaries
4
graph depth
32
components with no dependencies

Edges that cross a group boundary

What everything else is built from

Cut the package along the groups and these components end up in every piece — or behind a peer dependency of every piece.

Every figure in this section is computed from the installed package: dependencies come from the granular provider, groups from the registry. The library’s own document quotes the same argument measured at an older version — that is exactly why this page measures rather than quotes.

How an import reaches the bundle

Granularity is not a promise about tree-shaking. It is the shape of the package: a subpath per component, an entry per subpath, and CSS inside the component’s own chunk.

  1. You import a subpath
  2. the bundler takes that entry and its graph
  3. the component’s CSS travels in the same chunk
  4. the UnoCSS preset emits utilities for the components you listed, and for nothing else

The core and the companions

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 lives in a companion package with a peer on the core.

That is the one condition under which the decision «one package» is revisited: a family of components acquires a heavy external dependency the rest do not need. Charts, dates, rich text, media and the dashboard left for exactly that reason.

Where the library ends

It is not an application framework. Routing, data fetching, state and the build are yours; the design system gives components, foundations and the preset that ties them together — and stops there on purpose.

Read further

The full argument, with the history of the decision, is in the library repository.

Computed at build time from @feugene/granularity 0.41.0