Getting started
Install @tollerud/ui v4.6.13, wire Tailwind v4, and avoid the gotchas that break Server Components or purge component styles.
Choose your path
Most users: full design system. Footer-only and legacy Tailwind v3 are separate paths.
| Path | Install | CSS |
|---|---|---|
| Full system (most users) | @tollerud/ui + peers below | globals.css + source.css |
| Footer only | @tollerud/footer | Tollerud tokens still required |
| Tailwind v3 | Same peers | globals-v3.css + preset |
| NoirGlowBackground | + @paper-design/shaders-react | Optional peer |
Install
Core package plus required peers. One-time setup — peers stay in your app so you control versions.
Full Tollerud UI
npm install @tollerud/ui clsx tailwind-merge tailwindcss@4 \
@radix-ui/react-dialog @radix-ui/react-dropdown-menu @radix-ui/react-progress \
@radix-ui/react-slot @radix-ui/react-tabs @radix-ui/react-tooltip \
lucide-react framer-motion sonner
# Optional — NoirGlowBackground only
npm install @paper-design/shaders-reactRequired peers
As of v2.0.0, Radix, Lucide, Framer Motion, and Sonner are required peer dependencies — install them with the command above.
Peer dependencies by family
| Family | Packages | Needed for |
|---|---|---|
| Always | react, react-dom, clsx, tailwind-merge, tailwindcss | Every integration |
| Overlays & navigation | @radix-ui/react-dialog, @radix-ui/react-dropdown-menu, @radix-ui/react-tabs, @radix-ui/react-tooltip, @radix-ui/react-slot, @radix-ui/react-progress | Dialog, Sheet, Drawer, DropdownMenu, Tabs, Tooltip, Progress, Button asChild |
| Icons | lucide-react | Components with built-in icons |
| Motion | framer-motion | Animated components (e.g. GlowCard, charts) |
| Toasts | sonner | <Toaster /> / toast API — mount once at app root |
| Optional — glow | @paper-design/shaders-react | NoirGlowBackground only |
Footer only
npm install @tollerud/footer
import { Footer } from '@tollerud/footer'
<Footer />@tollerud/footer bundles clsx and tailwind-merge on purpose. You still need Tailwind with Tollerud tokens — @import "@tollerud/ui/globals.css" — so text-tollerud-* / bg-tollerud-* classes resolve.
Next.js starter
/getting-started/next-starter/Minimal App Router app with globals.css, source.css, sample page, and Toaster mounted.
# From the Tollerud/ui repo:
cp -R examples/next-starter my-app && cd my-app && npm install && npm run dev
# Or clone and copy:
# https://github.com/Tollerud/ui/tree/main/examples/next-starterStart with an AI agent
/getting-started/ai-agent/Copy a prompt into Cursor or Claude Code instead of wiring setup by hand. Run npx tollerud-ui-audit when the agent finishes.
Sync SKILL.md
Prompts reference SKILL.md for exports and gotchas. Let the agent fetch it, or sync https://github.com/Tollerud/ui/blob/main/SKILL.md into your project skills folder first.
New Next.js project
Set up a new Next.js App Router project with @tollerud/ui (Tollerud User Interface / Tollerud UI).
Requirements:
1. Use Next.js with App Router and Tailwind CSS v4 (PostCSS).
2. Install @tollerud/ui and all required peers:
npm install @tollerud/ui clsx tailwind-merge tailwindcss@4 @radix-ui/react-dialog @radix-ui/react-dropdown-menu @radix-ui/react-progress @radix-ui/react-slot @radix-ui/react-tabs @radix-ui/react-tooltip lucide-react framer-motion sonner
3. In app/globals.css, import BOTH:
@import "@tollerud/ui/globals.css";
@import "@tollerud/ui/source.css";
4. Mount <Toaster /> from @tollerud/ui in the root layout.
5. Build the sample home page with exported layout primitives and screen patterns (PageShell, Section, Stack, Button, etc.) — not hand-built min-h-screen/grid utilities. Follow https://design.tollerud.dev/recipes/ for screen structure.
6. Sync the Tollerud UI skill: fetch https://raw.githubusercontent.com/Tollerud/ui/main/SKILL.md and write it to .claude/skills/tollerud-ui/SKILL.md (or the equivalent skills folder for this agent).
7. Do NOT copy @tollerud/ui component source into components/ui. Import from @tollerud/ui only. Do NOT create a local cn() helper — use import { cn } from '@tollerud/ui'.
8. Style links with <Button asChild><Link … /></Button> or buttonVariants() — never nest <a> inside <button>.
9. Use Tollerud tokens (text-tollerud-yellow, bg-tollerud-noir-950) — never hardcode #FFFF00 or #0A0A0A.
10. When done, run npx tollerud-ui-audit and fix all errors before finishing.
If examples/next-starter exists in the Tollerud/ui repo, use it as the reference layout. Otherwise match its structure: globals.css + source.css, layout with Toaster, component-first sample page.
Tell me what you created and any audit output.Add to an existing project
Add @tollerud/ui (Tollerud User Interface / Tollerud UI) to this existing project.
Requirements:
1. Install @tollerud/ui and required peers if missing:
npm install @tollerud/ui clsx tailwind-merge tailwindcss@4 @radix-ui/react-dialog @radix-ui/react-dropdown-menu @radix-ui/react-progress @radix-ui/react-slot @radix-ui/react-tabs @radix-ui/react-tooltip lucide-react framer-motion sonner
2. Ensure the Tailwind entry CSS imports BOTH:
@import "@tollerud/ui/globals.css";
@import "@tollerud/ui/source.css";
3. Mount <Toaster /> near the app root if we use sonner toasts.
4. Sync SKILL.md from https://raw.githubusercontent.com/Tollerud/ui/main/SKILL.md into the project skills folder (.claude/skills/tollerud-ui/SKILL.md or equivalent).
5. Replace any vendored components/ui copies with imports from @tollerud/ui. Delete local cn() helpers — use import { cn } from '@tollerud/ui/utils'.
6. Do NOT copy new component source from the Tollerud UI repo into this app.
7. Use component-first composition: @tollerud/ui exports, then layout/screen patterns, then small Tailwind glue only. Screen starting points: https://design.tollerud.dev/recipes/
8. Fix Button/Link nesting: use asChild or buttonVariants() on links.
9. Replace hardcoded brand hex (#FFFF00, #0A0A0A) with Tollerud tokens.
10. Run npx tollerud-ui-audit from the app package root and fix all errors.
Summarize changes and audit results when done.Footer only
Add the Tollerud branded footer to this project using @tollerud/footer (footer-only — not the full Tollerud UI package).
Requirements:
1. npm install @tollerud/footer
2. Ensure Tailwind is configured with Tollerud tokens via @import "@tollerud/ui/globals.css" (footer-only apps still need token utilities for text-tollerud-* / bg-tollerud-*).
3. import { Footer } from '@tollerud/footer' and render <Footer /> in the layout.
4. Do not install the full @tollerud/ui peer set unless I ask for more components later.
Tell me what you changed.Tailwind v4
globals.css bundles tokens and layers. source.css handles @source scanning inside node_modules (pnpm, workspaces, Bun).
/* app/globals.css */
@import "@tollerud/ui/globals.css";
@import "@tollerud/ui/source.css";Without source.css (or a correct manual @source path), components render unstyled in production. See for tokens and for live examples.
Tailwind v3 (legacy)
Use the preset plus globals-v3.css when you cannot move to Tailwind v4 yet.
import type { Config } from 'tailwindcss'
import tollerudPreset from '@tollerud/ui/preset'
const config: Config = {
presets: [tollerudPreset],
content: [
'./app/**/*.{ts,tsx}',
'./components/**/*.{ts,tsx}',
'./node_modules/@tollerud/ui/dist/**/*.{js,mjs}',
],
}
export default config@import "tailwindcss/preflight";
@import "tailwindcss/utilities";
@import "@tollerud/ui/globals-v3.css";Imports
Named exports from the barrel, or subpaths for tree-shaking and smaller client boundaries.
import { Button, Card, Badge, cn, Monogram, DataTable } from '@tollerud/ui'
import { PageShell, Section, Stack } from '@tollerud/ui'
import { PageHeader, ResourceList } from '@tollerud/ui'
// Tree-shaken subpaths:
import { Button } from '@tollerud/ui/button'
import { cn } from '@tollerud/ui/utils'Consumer styling policy
Tailwind ships with Tollerud UI, but app code should use the component API as the primary design language.
Component-first by default
Use @tollerud/ui components first, exported layout primitives or screen patterns when available, and Tailwind only for small local spacing, alignment, or responsive glue.
import { Button, Card } from '@tollerud/ui'
export function DeployCard() {
return (
<Card>
<p>Ready to deploy.</p>
<div className="mt-6">
<Button variant="primary">Deploy</Button>
</div>
</Card>
)
}// Avoid: this bypasses Button variants, focus states, and brand tokens.
<button className="rounded-lg bg-yellow-400 px-4 py-2 text-black">
Deploy
</button>
// Avoid: move repeated branded layout into @tollerud/ui
// or a semantic feature component.
<section className="min-h-screen bg-black px-6 py-24">
<div className="mx-auto grid max-w-6xl gap-6 md:grid-cols-3">
{/* hand-built branded cards */}
</div>
</section>If a branded structure repeats across screens, add it to @tollerud/ui or compose a local semantic feature component. Do not copy package internals into components/ui, and import cn from the package instead of reimplementing it. For copy-paste screen starting points, see .
Consumer project checklist
/getting-started/consumer-checklist/Run npx tollerud-ui-audit before shipping. Fix errors for missing source.css, copied components/ui, hardcoded brand colors, and Button/Link nesting.
npx tollerud-ui-audit
# monorepo: npx tollerud-ui-audit ./apps/web
# without npx:
node node_modules/@tollerud/ui/scripts/audit-consumer-styling.mjs
# advisory CI (exit 0 even with errors):
npx tollerud-ui-audit --warn-onlyExit codes
Exit 0 when clean, or when only warnings exist with --warn-only. Exit 1 when errors are found — fix before merge.
Server Components
The bundle is marked 'use client'. Importing components or helpers like cn from a Server Component file is safe — your file does not become a Client Component.
Use asChild or buttonVariants for links
Button only renders a native <button>. Style links with asChild or buttonVariants() — never nest <a> inside <button>.
Toaster
Mount once near the app root when using sonner toasts.
import { Toaster } from '@tollerud/ui'
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<Toaster />
</body>
</html>
)
}Migrating from copied components
/getting-started/migrate-copied-ui/Replace vendored components/ui trees and local cn() helpers with package imports.
grep -rl "tollerud-yellow\|tollerud-noir\|tollerud-surface" src --include="*.tsx" --include="*.ts"Fix checklist
Install peers, swap imports to @tollerud/ui, delete copied files, sync SKILL.md for prop drift, add Toaster if using Sonner, then run npx tsc --noEmit and npx tollerud-ui-audit.
// Before
import { Button } from '@/components/ui/Button'
import { cn } from '@/lib/utils'
// After
import { Button } from '@tollerud/ui'
import { cn } from '@tollerud/ui/utils'Next steps
Explore the system by area.