Design system for Vue 3
Small pieces. Stronger systems.
Build consistent interfaces from composable components, foundations and utilities — importing exactly what you use, and nothing else.
| Component | CSS | JS |
|---|---|---|
GrCard | + 223 B | 1 870 B |
GrDialog | + 318 B | 9 789 B |
GrDataTable | + 705 B | 16 243 B |
GrSelect | + 2 335 B | 19 819 B |
GrDataTable costs three times less CSS than GrSelect and nearly as much JS. One number does not predict the other.
Gzipped, package only — your framework is yours and is not counted here.
Not a screenshot
A working screen, assembled from the same components.
- Conversion
- 4.8%
The same demo that stands on the GrStatistic page — nothing was written twice for the sake of a homepage.
Composable
136 export paths. Import a component, a composable or a single directive — the graph stops there.
Consistent
Every colour, space and radius is a role, not a value. Both themes are first-class.
Customizable
Rebrand by changing token values. Component source stays untouched.
Developer-first
Types, auto-import, IDE metadata and an accessibility contract that is tested, not claimed.
The same cost, four ways
One number would have been easier to print.
Every figure here comes from a build, gzipped, with the framework excluded — it is yours, not ours. Which of these four matters depends on what constrains you, so all four are on the page.
What adoption costs
8 250B, then almost nothing
base + GrButton8 250 B+ GrCard+ 223 B+ GrDialog+ 318 B+ GrDataTable+ 705 B+ GrSelect+ 2 335 BThe first component carries tokens, both themes and the base layer. The next four together add less than a third of that.
Whether every component is cheap
13.6×spread across the set
GrBadge1 455 BGrCard1 870 BGrAlert2 762 BGrButton3 391 BGrTabs4 819 BGrDialog9 789 BGrDataTable16 243 BGrSelect19 819 BNo. GrSelect weighs almost fourteen GrBadges. A library that claims every component is light is not measuring.
What you take on
0runtime dependencies
136 export paths
Nothing sits under the node. Your lockfile, your audit surface and your upgrade path stay yours — and 136 export paths mean the graph stops where you stop.
What a second theme costs
746B, at any size
1 · 7 504 B2 · 8 250 BThe figure barely moves between one component and all 77. Dropping dark mode is not where weight is saved.
Measured 2026-08-29 · core 0.38.0 · preset 0.15.0 · gzip
The model
Four layers, each built from the one below it. The name is the architecture.
01
Tokens
Colour, space, radius, motion and layering as named roles.
02
Components
77 in the core, and companions around it. Each one importable alone.
03
Patterns
Compositions that solve a task: forms, search, settings, overlays.
04
Interfaces
Whole screens. Components are useful; systems are valuable.
Foundations
A token is a role, not a hex code.
Colour, space, radius, motion and layering are named roles read from the package. Change the values and the components follow — 197 of them, in both themes.
--gr-bg--gr-fg--gr-card--gr-card-fg--gr-popover--gr-popover-fg--gr-muted--gr-muted-fg
From nothing to a button
Three commands, no scaffolding.
01Install
yarn add @feugene/granularity vue @floating-ui/dom02Import
import { GrButton } from '@feugene/granularity/components/GrButton'03Render
<GrButton tone="primary">Save</GrButton>
The full path — with the UnoCSS config and the three CSS imports — is on the getting started page. It fits on one screen too. Get started
Open development
Everything here is checkable.
- Core version
0.41.0- License
- LicenseRef-Granularity-EUC-1.1Apache-2.0 with an ethical use clause — source-available, not OSI-approved.
Start building with Granularity.
The shortest useful page is the getting started one. The rest of the documentation waits until you need it.