Project Details
Centralized Design System
A scalable design system with CSS tokens, Tailwind integration, and component library architecture.
About the Project
Architected and scaled a centralized design system to standardize UI components across multiple products. Implemented a token-based theming system using CSS variables mapped to Tailwind utilities, created a comprehensive typography scale, and built reusable component packages. The system uses Storybook for documentation and Lerna for monorepo management, accelerating product development cycles and ensuring UI consistency.
Token-Based Architecture
The design system uses CSS custom properties (variables) as design tokens, which are then mapped to Tailwind utilities. This approach provides:
- Centralized theming through CSS variables
- Type-safe Tailwind classes
- Easy theme switching and customization
- Consistent design language across products
Token Mapping Implementation
// globals.css - CSS Variables (Design Tokens)
:root {
--primary: #2563eb;
--primary-foreground: #ffffff;
--muted: #f8fafc;
--muted-foreground: #64748b;
--border: #e2e8f0;
--radius: 0.5rem;
}
// tailwind.config.js - Token Mapping
colors: {
primary: {
DEFAULT: "var(--primary)",
foreground: "var(--primary-foreground)"
},
muted: {
DEFAULT: "var(--muted)",
foreground: "var(--muted-foreground)"
},
border: "var(--border)"
},
borderRadius: {
lg: "var(--radius)",
md: "calc(var(--radius) - 2px)"
}
// Usage in Components
<button className="bg-primary text-primary-foreground rounded-lg">
Click me
</button>System Architecture
The design system follows a layered architecture, from foundational tokens to application components.
Typography Scale
A comprehensive typography system with semantic classes that scale responsively:
.title-1.title-3.body-1.caption-1// Typography Utilities in Tailwind Config
".title-1": {
fontSize: theme("fontSize.5xl"),
fontWeight: theme("fontWeight.bold")
},
".body-1": {
fontSize: theme("fontSize.base"),
fontWeight: theme("fontWeight.normal")
},
".caption-1": {
fontSize: theme("fontSize.xs"),
fontWeight: theme("fontWeight.semibold")
}
// Responsive scaling at md breakpoint
"@screen md": {
".title-1": {
fontSize: theme("fontSize.7xl")
}
}Component Structure
Components are organized in layers, from base UI components to application-specific wrappers.
Lerna Monorepo Packaging
Components are packaged and versioned independently using Lerna, enabling:
- Independent versioning per component package
- Centralized dependency management
- Automated publishing to NPM registry
- Easy updates without breaking changes
Button Component Packaging Workflow
Here's how a button component flows through the Lerna packaging pipeline:
// 1. Base Component (packages/button/src/Button.tsx)
import { cva } from "class-variance-authority";
const buttonVariants = cva(
"inline-flex items-center justify-center rounded-md",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
outline: "border border-input bg-background hover:bg-accent",
ghost: "hover:bg-accent hover:text-accent-foreground"
},
size: {
default: "h-10 px-4 py-2",
sm: "h-9 px-3",
lg: "h-11 px-8"
}
}
}
);
export const Button = ({ variant, size, ...props }) => (
<button className={buttonVariants({ variant, size })} {...props} />
);
// 2. Lerna Package Configuration (packages/button/package.json)
{
"name": "@component-library/button",
"version": "0.1.50",
"main": "dist/index.js",
"types": "dist/index.d.ts"
}
// 3. Lerna Commands
lerna version # Bump version (independent mode)
lerna publish # Publish to NPM registry
lerna run build # Build all packages
// 4. Design Package Wrapper (components/design-packages/buttonPackage.js)
import { Button } from "@component-library/button";
export { Button as DesignButton };
// 5. Application Usage
import { DesignButton } from "@/components/design-packages/buttonPackage";
<DesignButton variant="default" size="lg">Submit</DesignButton>Component Structure
Components flow through multiple layers, from source code to published packages to application usage.
Color System
A semantic color system with variants for different use cases:
Key Benefits
Consistency
Standardized tokens ensure visual consistency across all products and components.
Maintainability
Centralized tokens make theme updates simple and propagate changes automatically.
Developer Experience
Type-safe Tailwind classes and semantic component APIs improve productivity.
Scalability
Monorepo structure with Lerna enables independent versioning and distribution.