Start
Tokens as a package, components as code
Two halves. The tokens — colours, type, motion, the Tailwind preset — come from npm and upgrade in one place. The components are copied into your app with the shadcn CLI and become yours to adapt.
1 · The tokens package
bun add @fastrp/design-tokensPeer dependency: tailwindcss@^3.4. Tailwind 4 is not supported — the game cannot run it.
2 · The preset and the stylesheet
tailwind.config.ts
import { fastPreset } from '@fastrp/design-tokens/preset';
import type { Config } from 'tailwindcss';
export default {
presets: [fastPreset],
content: ['./src/**/*.{ts,tsx}'],
} satisfies Config;globals.css
@import '@fastrp/design-tokens/tokens.css';
@tailwind base;
@tailwind components;
@tailwind utilities;What the preset leaves alone
It does not setscreens, corePlugins, the spacing scale or content. The game keeps its breakpoints and its backdropBlur: false.3 · cn() that knows the preset
Plain
twMerge reads text-display-1 as a colour and drops it when text-white follows. Extend it once.lib/utils.ts
import { fastTwMergeConfig } from '@fastrp/design-tokens/tw-merge';
import { type ClassValue, clsx } from 'clsx';
import { extendTailwindMerge } from 'tailwind-merge';
const twMerge = extendTailwindMerge(fastTwMergeConfig);
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}4 · Components from the registry
Add the registry to
components.json, then add components by name. Files land in components/ds/, each marked // @fast-ds name@version under its imports so a copy can be compared with the registry later.components.json
{
"registries": {
"@fastrp": "https://design.fast-rp.com/r/{name}.json"
}
}bunx shadcn@3 add @fastrp/section-heading5 · The font
Load Barlow as --font-sans and Barlow Condensed as --font-display, with the latin-ext subset. See Typography.