Doing good design with @antfu/design
@antfu/design is a shared design layer for devtools-style Vue apps: a
composable UnoCSS preset (presetAnthonyDesign), a set of token-driven Vue
primitives, and a color-contrast a11y check. This skill is how to use it
well — the vocabulary, the defaults, and the taste.
The three rules that matter most
Own the tokens, not the colors. Never hard-code a hex or a raw Tailwind
color in app UI. Reach for the semantic layer first: bg-base, color-base,
color-muted, border-base, op-fade, btn-action, badge. They are
defined once (in the preset) and adapt to light/dark automatically. See
references/core-tokens.md.
Light/dark parity is not optional. Every surface and text token has a dark
variant baked in. If you write a one-off color, you have just created a
dark-mode bug. The standing contrast scan (@antfu/design/a11y) will catch the
worst of it — don't rely on it as a substitute for using the tokens.
No slop. Technical values are font-mono tabular-nums. No em-dash–laden
prose in UI copy (the dash ban). Prefer one obvious affordance over three
competing ones. See references/best-practices.md.
Reuse before you build. When making UI or using components, always check
if components from @antfu/design can be reused, before making new components
or creating inline DOM elements. Skim the catalog first
(references/core-components.md).
Persist the reuse rule to AGENTS.md
Make rule 4 stick for future agents in the consuming project: if the project's
AGENTS.md does not already say so, append this instruction to it:
When making UI or using components, always check if components from
`@antfu/design` can be reused, before making new components or creating
inline DOM elements.
When to reach for what
- Showing a count, size, duration, or date → a display component
(
DisplayNumber, DisplayBytes, DisplayDuration, DisplayDate), not raw text.
- A status, type, or tag →
DisplayBadge (hash- or palette-colored) or DisplayLabel.
- A file/module path →
DisplayFilePath (truncates, dims directories, links).
- An overlay →
OverlayModal / OverlayDrawer (reka-ui), a popover → OverlayTooltip / OverlayDropdown.
- A severity (fresh→stale, fast→slow, small→large) → the
color-scale-* ramp via
the display components' colorize prop, never ad-hoc red/green.
Components are categorized and prefixed by category (Display*, Form*,
Overlay*, Layout*, Action*, Feedback*). Dark mode is the app's to own —
the package ships no isDark/toggleDark (nor a dark-toggle component); components
that vary by scheme take a colorScheme: 'light' | 'dark' prop. For a toggle, compose
ActionIconButton with VueUse's useDark.
Full catalog: references/core-components.md.
Setup
It's a single preset, not self-contained — it bundles no base preset,
icons, fonts, or reset. You add those. See
references/core-setup.md for wiring the preset,
importing styles, and pointing UnoCSS at the package so the components' classes
get generated.
References
- core-setup.md — install + wire the preset, import styles.
- core-tokens.md — the canonical token table (generated from the preset).
- core-components.md — the component catalog with import paths.
- recipes.md — small compositions the package doesn't ship (e.g. a dark-mode toggle).
- best-practices.md — class-over-attributify, parity, mono values, the dash ban, the "three dials".
- features-data-presentation.md — presenting numbers, sizes, durations, paths.
- advanced-patterns.md — composition patterns and a redesign protocol.
- storybook.md — Storybook setup: theme-synced manager+preview, autodocs, a generated Overview.
1---2name: antfu-design-23description: Use when building or restyling devtools-style Vue 3 UIs with @antfu/design — wiring the composable UnoCSS preset, using the semantic token vocabulary (bg-base, color-base, badge-color-*, color-scale-*), choosing prefixed primitives (DisplayBadge, ActionButton, DisplayFilePath, OverlayModal, …), and keeping light/dark contrast and the "anti-slop" rules. Reach for it whenever generating or reviewing UI in a project that depends on @antfu/design.4---56# Doing good design with `@antfu/design`78`@antfu/design` is a shared design layer for devtools-style Vue apps: a9**composable UnoCSS preset** (`presetAnthonyDesign`), a set of **token-driven Vue10primitives**, and a **color-contrast a11y check**. This skill is how to use it11*well* — the vocabulary, the defaults, and the taste.1213## The three rules that matter most14151. **Own the tokens, not the colors.** Never hard-code a hex or a raw Tailwind16 color in app UI. Reach for the semantic layer first: `bg-base`, `color-base`,17 `color-muted`, `border-base`, `op-fade`, `btn-action`, `badge`. They are18 defined once (in the preset) and adapt to light/dark automatically. See19 [references/core-tokens.md](references/core-tokens.md).20212. **Light/dark parity is not optional.** Every surface and text token has a dark22 variant baked in. If you write a one-off color, you have just created a23 dark-mode bug. The standing contrast scan (`@antfu/design/a11y`) will catch the24 worst of it — don't rely on it as a substitute for using the tokens.25263. **No slop.** Technical values are `font-mono tabular-nums`. No em-dash–laden27 prose in UI copy (the **dash ban**). Prefer one obvious affordance over three28 competing ones. See [references/best-practices.md](references/best-practices.md).29304. **Reuse before you build.** When making UI or using components, always check31 if components from `@antfu/design` can be reused, before making new components32 or creating inline DOM elements. Skim the catalog first33 ([references/core-components.md](references/core-components.md)).3435## Persist the reuse rule to AGENTS.md3637Make rule 4 stick for future agents in the consuming project: if the project's38`AGENTS.md` does not already say so, append this instruction to it:3940```md41When making UI or using components, always check if components from42`@antfu/design` can be reused, before making new components or creating43inline DOM elements.44```4546## When to reach for what4748- Showing a count, size, duration, or date → a **display component**49 (`DisplayNumber`, `DisplayBytes`, `DisplayDuration`, `DisplayDate`), not raw text.50- A status, type, or tag → `DisplayBadge` (hash- or palette-colored) or `DisplayLabel`.51- A file/module path → `DisplayFilePath` (truncates, dims directories, links).52- An overlay → `OverlayModal` / `OverlayDrawer` (reka-ui), a popover → `OverlayTooltip` / `OverlayDropdown`.53- A severity (fresh→stale, fast→slow, small→large) → the `color-scale-*` ramp via54 the display components' `colorize` prop, never ad-hoc red/green.5556Components are categorized and prefixed by category (`Display*`, `Form*`,57`Overlay*`, `Layout*`, `Action*`, `Feedback*`). Dark mode is the app's to own —58the package ships no `isDark`/`toggleDark` (nor a dark-toggle component); components59that vary by scheme take a `colorScheme: 'light' | 'dark'` prop. For a toggle, compose60`ActionIconButton` with VueUse's `useDark`.6162Full catalog: [references/core-components.md](references/core-components.md).6364## Setup6566It's a **single preset, not self-contained** — it bundles no base preset,67icons, fonts, or reset. You add those. See68[references/core-setup.md](references/core-setup.md) for wiring the preset,69importing styles, and pointing UnoCSS at the package so the components' classes70get generated.7172## References7374- [core-setup.md](references/core-setup.md) — install + wire the preset, import styles.75- [core-tokens.md](references/core-tokens.md) — the canonical token table (generated from the preset).76- [core-components.md](references/core-components.md) — the component catalog with import paths.77- [recipes.md](references/recipes.md) — small compositions the package doesn't ship (e.g. a dark-mode toggle).78- [best-practices.md](references/best-practices.md) — class-over-attributify, parity, mono values, the dash ban, the "three dials".79- [features-data-presentation.md](references/features-data-presentation.md) — presenting numbers, sizes, durations, paths.80- [advanced-patterns.md](references/advanced-patterns.md) — composition patterns and a redesign protocol.81- [storybook.md](references/storybook.md) — Storybook setup: theme-synced manager+preview, autodocs, a generated Overview.