Opinionated Rules to build, maintain, and scale React + TypeScript design-system driven front-ends.
Building consistent, scalable frontend applications shouldn't require reinventing the wheel for every project. Yet most React developers find themselves copying components between projects, wrestling with design inconsistencies, and spending more time on UI implementation than business logic.
You're likely dealing with these workflow killers daily:
The root problem? Most teams treat UI components as throwaway code instead of a strategic design system investment.
These Cursor Rules transform your development approach by treating your design system as a first-class product. Instead of ad-hoc component development, you'll build a systematic, token-driven foundation that scales across projects and teams.
What This Changes:
Stop building buttons from scratch. With atomic design patterns and design tokens, new components inherit spacing, colors, and interactions automatically.
// Before: Manual styling every time
const CustomButton = styled.button`
padding: 12px 24px;
background: #0055ff;
border-radius: 8px;
/* ... 20 more lines */
`
// After: Token-driven system
const Button = styled.button`
${({ variant, size }) => css`
padding: ${theme.space[size]};
background: ${theme.color.brand[variant]};
border-radius: ${theme.radius.medium};
`}
`
Design tokens eliminate the guesswork. Your components automatically stay consistent across projects because they reference the same foundational values.
Built-in WCAG compliance with automated testing means you catch accessibility issues in development, not during security reviews.
Discriminated unions for variant props eliminate runtime errors and provide excellent developer experience with autocomplete.
interface ButtonProps {
variant: "primary" | "secondary" | "ghost"
size: "small" | "medium" | "large"
disabled?: boolean
}
// TypeScript prevents invalid combinations and provides autocomplete
Time Cost: 2-3 hours per component, multiplied across projects
Time Cost: 15 minutes for system-wide updates
// 1. Define token-based component
export function Button({ variant = "primary", size = "medium", ...props }: ButtonProps) {
return (
<StyledButton
variant={variant}
size={size}
data-testid="button"
{...props}
/>
)
}
// 2. Storybook automatically generates documentation
export default {
title: 'Atoms/Button',
component: Button,
docs: { autodocs: true }
}
// 3. Tests validate accessibility and functionality
test('Button meets WCAG contrast requirements', async () => {
render(<Button>Click me</Button>)
const results = await axe(container)
expect(results).toHaveNoViolations()
})
Your design tokens flow from Figma → JSON → TypeScript automatically:
{
"color": {
"brand": {
"primary": { "value": "#0055ff" },
"secondary": { "value": "#6366f1" }
}
},
"space": {
"small": { "value": "8px" },
"medium": { "value": "16px" }
}
}
Style Dictionary compiles these to TypeScript interfaces and CSS custom properties, ensuring type safety and consistency.
# Set up the base structure
mkdir src/{atoms,molecules,organisms,templates,pages,hooks,tokens,styles,utils}
# Install core dependencies
pnpm add react@^18 typescript styled-components@^6 @storybook/react
pnpm add -D style-dictionary @changesets/cli chromatic
Create style-dictionary.config.js:
module.exports = {
source: ['tokens/*.json'],
platforms: {
ts: {
transformGroup: 'ts',
buildPath: 'src/tokens/',
files: [{
destination: 'index.ts',
format: 'typescript/es6-declarations'
}]
}
}
}
// src/atoms/Button/Button.tsx
interface ButtonProps {
variant?: "primary" | "secondary" | "ghost"
size?: "small" | "medium" | "large"
disabled?: boolean
children: React.ReactNode
className?: string
"data-testid"?: string
}
export function Button(props: ButtonProps): JSX.Element {
const { variant = "primary", size = "medium", disabled = false, ...rest } = props
if (__DEV__) {
invariant(variant in variantMap, `Button: unknown variant ${variant}`)
}
return <StyledButton variant={variant} size={size} disabled={disabled} {...rest} />
}
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true
}
}
// Button.test.tsx
import { axe } from '@axe-core/react'
import { render } from '@testing-library/react'
test('Button is accessible', async () => {
const { container } = render(<Button>Click me</Button>)
const results = await axe(container)
expect(results).toHaveNoViolations()
})
# .github/workflows/design-system.yml
- name: Type Check
run: pnpm typecheck
- name: Test
run: pnpm test --run
- name: Build Tokens
run: pnpm build:tokens
- name: Visual Testing
run: pnpm chromatic
Your design system becomes a competitive advantage. New features ship faster, design debt disappears, and your team focuses on solving business problems instead of wrestling with UI inconsistencies.
Ready to transform your frontend development workflow? These Cursor Rules provide the opinionated structure that successful design systems require. Stop reinventing components and start building scalable, accessible, token-driven interfaces that your entire team will love working with.
The difference between good developers and great ones isn't just technical skill—it's the systems and processes they build to multiply their effectiveness. Your design system revolution starts now.
You are an expert in React, TypeScript, styled-components, Storybook, Figma, and design-token pipelines.
Key Principles
- Treat the design system (DS) as a long-lived product with its own backlog, roadmap, and KPIs.
- Strive for single-source-of-truth: tokens → components → documentation all generated from the same JSON token files.
- Accessibility (WCAG 2.2 AA) is a non-negotiable requirement; colour, keyboard, and ARIA must be validated in CI.
- Adopt Atomic Design hierarchy (atoms → molecules → organisms → templates → pages) for folder layout and Storybook stories.
- Prefer pure, functional React components; avoid class components and side-effects in render paths.
- Limit public API surface; expose only stable, semantic props. Mark all experimental props with `@internal` and hide from docs.
- Enforce semantic versioning with clear deprecation strategy (`@deprecated` JSDoc, console warning, removal after 2 minor releases).
- Continuous documentation: every PR that changes tokens, components, or patterns must update MDX docs & Figma descriptions.
TypeScript
- Always compile with `strict: true`, `noUncheckedIndexedAccess: true`, and `exactOptionalPropertyTypes: true`.
- Component function signature: `export function Button(props: ButtonProps): JSX.Element {}`.
- Prefer `interface` for component props and theming contracts; use `type` for unions/intersections.
- Never use `any`; fall back to `unknown` + type-narrowing if inevitable.
- Use exhaustive discriminated unions for variant props (e.g., `variant: "primary" | "secondary" | "ghost"`).
- Top-level barrel exports per atomic level: `index.ts` re-exports internal files; consumers only import from level root.
JavaScript Conventions (runtime)
- No semicolons (standardJS style) except when beginning a line with `[`, `(`, `/`, or template literal.
- 2-space indentation, single quotes, trailing comma `all`.
- Destructure props at function entry; rename w/ default value when needed: `const { disabled = false } = props`.
React
- Use React 18+ with automatic batching.
- Hooks rules: create DS-specific hooks under `hooks/` (e.g., `useTheme`, `useMediaQuery`); names always start with `use`.
- Avoid context overuse; prefer prop drilling up to 3 levels before creating new React Context.
- For styling, use `styled-components` 6+ with the `css` helper; never interpolate unescaped user content.
- All components accept `className?` and `data-testid?` for integrations.
- Compose motion/interaction via `framer-motion` where complex animation is needed; keep 60 fps target.
Error Handling & Validation
- Validate props at runtime in development builds with `tiny-invariant` or custom assertions; strip in production.
- Early-return for invalid states, e.g.
```ts
if (__DEV__) invariant(size in sizeMap, `Button: unknown size ${size}`)
```
- Theming lookup must fallback: if token not found, log once in dev, render placeholder colour `#f00`.
- Provide boundary components (`ErrorBoundary`) around experimental organisms and templates.
- Storybook has an automated `axe-core` accessibility test story per component; fail CI on violation.
Design Tokens
- All tokens defined in `tokens/*.json` following W3C Design Token Community Group format.
- Tokens are compiled with Style Dictionary → `dist/tokens.(ts|scss|json)` on `prebuild`.
- Token names use `kebab-case`, categories: `color`, `space`, `radius`, `shadow`, `typography`.
- Example token:
```json
{
"color": {
"brand": { "primary": { "value": "#0055ff" } }
}
}
```
Theme Provider Pattern
- Wrap root in `<ThemeProvider theme={themeObject}>`; theme object typed with `DefaultTheme` (sc-theming).
- Switching theme: use `React.Context` + `useTheme`; persist selection in `localStorage` key `ds-theme`.
Storybook
- Structure stories mirroring Atomic levels: `Atoms/Button/Button.stories.tsx`.
- Use CSF3 stories; co-locate with component file (`Button.tsx` next to `Button.stories.tsx`).
- Automatic docs: `docs: { autodocs: true }` in default export.
- Integrate `controls` for all variant props; names match prop name exactly.
- Add `play` function with `@storybook/testing-library` for critical interaction flows.
Testing
- Unit tests with Vitest + @testing-library/react; snapshot only for static token exports.
- Visual regression with Chromatic; threshold 0.08%.
- Integrate per-PR lighthouse CI using `@lhci/cli` for performance budgets.
Performance
- Tree-shakable exports: `package.json#exports` lists atomic entry points.
- Use `/*#__PURE__*/` comments on styled-component wrappers to assist dead-code elimination.
- Load fonts via `@font-face` `display: swap` and include preconnect to font CDNs.
Accessibility
- Colour contrast ≥ 4.5:1 by default; token build pipeline rejects failures.
- Non-text contrast meets 3:1 (focus states, icons, charts).
- Provide keyboard focus ring on all interactive atoms; ring colour derived from `color.focus` token.
- Components include `aria-*` props passthrough.
Versioning & Release
- Release via Changesets; auto bump semver and generate changelog.
- Deprecations: mark with `/** @deprecated since 3.2 – use <NewButton> */`; console.warn in dev.
Documentation
- Zeroheight mirrors Figma components; embed Storybook iFrame per component.
- Every token and component includes “Why” section explaining rationale.
Directory Layout
```
src/
atoms/
molecules/
organisms/
templates/
pages/
hooks/
tokens/ # generated, don’t edit
styles/
utils/
```
Security
- Escape interpolated dynamic styles with `css` helper; never string-concatenate untrusted input.
- Lint for dangerous HTML with eslint-plugin-jsx-a11y and eslint-plugin-react-security.
CI Pipeline
1. `pnpm typecheck`
2. `pnpm test --run` (unit + a11y)
3. `pnpm build` (token build + TS `emitDeclarationOnly`)
4. Chromatic & LHCI
5. Publish to npm and GitHub Packages after main passes.