A structured guide for building production-ready component libraries and design systems. Covers architecture, tokens, components, documentation, theming, testing, and publishing.
GoalStart hereSet up monorepo + buildArchitectureDefine design tokensreferences/tokens.mdBuild componentsreferences/component-patterns.mdStorybook setupreferences/storybook-setup.mdTheming / dark modereferences/theming.mdTesting strategyreferences/testing-strategy.mdRelease pipelinereferences/release-pipeline.md
Use pnpm workspaces + Turborepo for monorepo management.
text
my-design-system/
├── packages/
│ ├── tokens/ # Design tokens (CSS vars, JS objects)
│ ├── icons/ # SVG icon components
│ ├── components/ # Core UI components
│ ├── themes/ # Theme definitions
│ └── utils/ # Shared utilities (cn, clsx, etc.)
├── apps/
│ └── docs/ # Storybook documentation site
├── package.json # Root workspace config
├── pnpm-workspace.yaml
├── turbo.json
└── tsconfig.base.json
bash
# Initialize monorepo
mkdir my-design-system && cd my-design-system
pnpm init
pnpm add -D turbo -w
# Create workspace config
echo "packages:\n - 'packages/*'\n - 'apps/*'" > pnpm-workspace.yaml
turbo.json — task pipeline:
json
{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"build": { "dependsOn": ["^build"], "outputs": ["dist/**"] },
"dev": { "cache": false, "persistent": true },
"test": { "dependsOn": ["^build"] },
"lint": {}
}
}
ToolBest forNotesVite + vite-plugin-dtsReact/Vue componentsFast, ESM-firsttsupUtility packagesZero-config, dual CJS/ESMRollupFine-grained controlMore config overhead
Recommended packages/components/package.json:
json
{
"name": "@myds/components",
"version": "0.1.0",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.js",
"require": "./dist/index.cjs",
"types": "./dist/index.d.ts"
}
},
"scripts": {
"build": "tsup src/index.ts --format cjs,esm --dts",
"dev": "tsup src/index.ts --format cjs,esm --dts --watch"
}
}
Design tokens are the single source of truth for visual decisions.
Read references/tokens.md for the complete token schema, naming conventions, CSS variable patterns, and multi-brand token examples.
bash
# Install Style Dictionary (token transformation tool)
pnpm add -D style-dictionary -w
Token files live in packages/tokens/src/. Style Dictionary transforms them to CSS variables, JS/TS constants,
and platform-specific outputs (iOS, Android).
Core token categories: color, typography, spacing, border-radius, shadow, z-index, motion.
Every component should follow consistent conventions for long-term maintainability.
Read references/component-patterns.md for detailed patterns: file structure, Props API design, compound components, polymorphic components, accessibility requirements, and documentation templates.
anyforwardRef for all leaf elements (React)aria-* attributes — never ship an inaccessible componentdata-testid — include for E2E testabilitytext
Button/
├── Button.tsx # Component implementation
├── Button.types.ts # Props interface & type exports
├── Button.test.tsx # Unit + interaction tests
├── Button.stories.tsx # Storybook stories
└── index.ts # Public barrel export
Storybook is the primary documentation and development environment.
Read references/storybook-setup.md for full configuration: addon setup, autodocs, MDX pages, controls, theming the Storybook UI, and deployment.
bash
cd apps/docs
pnpm dlx storybook@latest init
# Select React + Vite when prompted
Essential addons:
@storybook/addon-essentials (controls, actions, docs, viewport)@storybook/addon-a11y (accessibility audit)@storybook/addon-themes (theme switching)storybook-addon-pseudo-states (hover/focus/active states)Read references/theming.md for full theming architecture: CSS custom properties strategy, dark mode implementation (media query vs. class-based), ThemeProvider pattern for React, and Vue 3 provide/inject approach.
Tokens define semantic aliases that point to primitive values:
css
/* Primitive */
--color-blue-500: #3b82f6;
/* Semantic (theme-aware) */
[data-theme="light"] { --color-primary: var(--color-blue-500); }
[data-theme="dark"] { --color-primary: var(--color-blue-400); }
Components reference semantic tokens only — never primitives directly.
Read references/testing-strategy.md for the full pyramid: unit tests (Vitest), interaction tests (Testing Library), visual regression (Chromatic/Percy), and accessibility automation.
text
[Visual Regression] ← Chromatic / Percy
[Interaction Tests] ← @testing-library/react
[Unit / Logic Tests] ← Vitest
Minimum bar per component:
Read references/release-pipeline.md for the complete release flow: Changesets setup, versioning strategy, automated changelog, CI/CD pipeline, and npm publishing.
bash
pnpm add -D @changesets/cli -w
pnpm changeset init
Workflow:
pnpm changeset — create a changeset (describe changes)pnpm changeset version — bump versions + update CHANGELOG.mdpnpm changeset publish — publish to npmMost patterns apply to Vue 3 with minor adaptations:
defineProps<T>() with TypeScript genericsexpose() replaces React's forwardRefprovide/inject replaces React Context@vue/test-utils + VitestLayerReactVue 3Monorepopnpm + Turborepopnpm + TurborepoBuildtsup / Vitetsup / ViteTokensStyle DictionaryStyle DictionaryDocsStorybook 8Storybook 8Unit testsVitest + Testing LibraryVitest + @vue/test-utilsVisual regressionChromaticChromaticReleaseChangesetsChangesetsCSSCSS Modules / CSS-in-JSCSS Modules / scoped SFC