Getting started
Three commands to a fully-themed app with the DS's a11y and responsive contracts active. Then keep installing primitives one at a time as you need them.
Install the full CSS baseline
The @interlace/theme bundle ships the styles/interlace/index.css barrel plus the six leaves it imports (tokens → foundation → preflight → theme → interlace-theme → themes/harbor). Import the barrel and the cascade order — including the part that is not guessable, where a theme file must come after interlace-theme — is handled for you. One command lands the type / spacing / radius scales, the WCAG 2.2 SC 2.4.13 focus ring, the [data-min-viewport] container contract, reduced-motion respect, and the burnt-orange brand palette.
npx shadcn@latest add @interlace/theme@import "tailwindcss";
@import "./styles/interlace/index.css";Install the layout starter
Six primitives that compose every page — Container, Section, Stack, Grid, Box, Typography. The LAYOUT_PHILOSOPHY contract is satisfied in one install.
npx shadcn@latest add @interlace/layout-starterInstall the a11y starter
SkipLink + VisuallyHidden + FocusRing + useReducedMotion. Drops the three primitives every consumer needs on day one plus the hook every animated primitive uses to honor the OS preference.
npx shadcn@latest add @interlace/a11y-starterBefore you install: the token namespace is shared
This baseline claims 116 Tailwind v4 @theme keys — 54 of them in the --color-* namespace. Those keys are global. Where your app already claims the same key, exactly one registration survives, and nothing warns: not the compiler, not the linter, not your tests.
The one that catches people: --color-accent. In shadcn's vocabulary accent is the near-white hover surface, not the brand highlight. If your accent is your brand colour, every bg-accent in your app turns #fef4ed — white-on-white, at paint time, with a green build.
Check the full claimed list against your own @theme block before you install: token namespace & migration.
Opt into the min-viewport dev outline
Every Interlace primitive declares its smallest viable viewport via data-min-viewport="320|480|768". In development, add the data-interlace-dev flag to your <body> and the preflight contract will draw a dashed outline around any primitive rendered in a container narrower than its declared minimum. Strip the attribute in production.
<body
data-interlace-dev={process.env.NODE_ENV !== 'production' ? '' : undefined}
>
{children}
</body>Alternate: install the CSS as an npm package
If you don't want to vendor the source via the shadcn CLI, install the CSS baseline as a versioned npm package:
npm i @interlace/foundation@import "@interlace/foundation";
/* or just the focus + min-viewport contract */
@import "@interlace/foundation/preflight.css";The package follows semver against the CSS contract — patch updates preserve contrast + cascade behavior; majors are reserved for token renames or cascade reorderings. See @interlace/foundation README.
What the three commands give you
- Focus ring (WCAG 2.2 SC 2.4.13)
- 2 px solid, 2 px offset, ≥3:1 contrast against the adjacent surface — on every interactive element, in both light and dark.
- Min-viewport contract
- Every primitive carries
data-min-viewport; the dev-mode outline warns when one renders below its declared floor. Production strips the warning. - Reduced-motion respect
prefers-reduced-motion: reduceclamps every animation to 0.01ms globally; client primitives also gate on theuseReducedMotionhook.- Type / spacing / radius scales
- h1–h6, body, long, ui, ui-sm, caption, code variants. Six-step spacing (8/16/24/40/64/96 px). Three-step radius (8/12/16 px).
- Brand palette (AAA-cleared)
- Burnt orange: #7d350c light (8.80:1 on white); #fbb99a dark (11.79:1 on near-black). Repointed from Tailwind violet (July 2026) entirely via
@layer interlace.brand— the same surface you'd use to ship your own brand. Five chart-series hues. - Skip-to-main + sr-only contract
SkipLinkfor WCAG 2.4.1 Bypass Blocks;VisuallyHiddenfor the screen-reader-only contract. Both shipped, both component-form.
Next
From here, install primitives one at a time as you need them. Every primitive page lists its install command, anatomy, variants, R-rule compliance, and source. Shipping your own brand? Override @layer interlace.brand — see Theme Authoring.
Proof the install works
Not a claim — a run. CI creates a brand-new Next.js + Tailwind v4 app from scratch, runs npx shadcn init, adds every item in this registry through the real CLI, and then builds the result. The outcome is committed to apps/registry/e2e-install-results.json — this page reads that file, it does not summarise it by hand.
Every item the run attempted resolved and wrote its files.
Into a tree that had never seen this design system before.
next build compiled and type-checked every installed source — the CLI copying a file is not the same as the file compiling.
- ✓
createNextAppA brand-new Next.js + Tailwind v4 app, created from scratch — not a fixture kept alive between runs. - ✓
consumerProfileconsumerProfile - ✓
addEvery registry item installed through the realnpx shadcn addCLI, resolving registry dependencies as it went. - ✓
cnDependencycnDependency - ✓
originProvenanceoriginProvenance - ✓
versionBannerversionBanner - ✓
cssWiredThe DS stylesheets landed in the app’s CSS in cascade-correct order. - ✓
buildnext buildcompiled and type-checked the installed sources in a project that has never seen this DS before.
Run 12 Aug 2026, in 92s. Reproduce it with npm run registry:e2e in the repo.