Piyush Arora.
ProjectsAboutResumeContact
Back to Projects

Project Details

Centralized Design System

A scalable design system with CSS tokens, Tailwind integration, and component library architecture.

Design SystemCSS TokensTailwind CSSStorybookLernaReact

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 1 - Display Heading
.title-3
Title 3 - Section Heading
.body-1
Body 1 - Primary text content
.caption-1
Caption 1 - Small labels
// 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:

Primary
#2563eb
Muted
#f8fafc
Success
#059669
Destructive
#e11d48

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.