惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Palo Alto Networks Blog
大猫的无限游戏
大猫的无限游戏
Martin Fowler
Martin Fowler
GbyAI
GbyAI
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
量子位
T
The Blog of Author Tim Ferriss
Y
Y Combinator Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
CERT Recently Published Vulnerability Notes
Recent Announcements
Recent Announcements
A
About on SuperTechFans
aimingoo的专栏
aimingoo的专栏
P
Privacy International News Feed
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
博客园 - 叶小钗
L
Lohrmann on Cybersecurity
G
GRAHAM CLULEY
T
The Exploit Database - CXSecurity.com
Hugging Face - Blog
Hugging Face - Blog
P
Proofpoint News Feed
NISL@THU
NISL@THU
博客园 - Franky
C
Cybersecurity and Infrastructure Security Agency CISA
The Register - Security
The Register - Security
M
MIT News - Artificial intelligence
Know Your Adversary
Know Your Adversary
A
Arctic Wolf
F
Full Disclosure
T
Threat Research - Cisco Blogs
P
Privacy & Cybersecurity Law Blog
The Hacker News
The Hacker News
博客园 - 【当耐特】
D
Docker
T
Tailwind CSS Blog
S
SegmentFault 最新的问题
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Jina AI
Jina AI
Help Net Security
Help Net Security
V
Visual Studio Blog
小众软件
小众软件
B
Blog
Vercel News
Vercel News
云风的 BLOG
云风的 BLOG
N
News and Events Feed by Topic
Forbes - Security
Forbes - Security
N
Netflix TechBlog - Medium
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
C
Cisco Blogs
Security Archives - TechRepublic
Security Archives - TechRepublic

freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

Learn Command Line Interface (CLI) Development with Dart: From Zero to a Fully Published Developer Tool How to Build a Live Options Database in Python – A Complete Guide How to Migrate to S3 Native State Locking in Terraform How to Use SCons to Build Software Projects [Full Handbook] How to Run Open Source LLMs Locally and in the Cloud QuRT: The Real-Time OS Inside Your Phone's Processor [Full Handbook] The Real Infrastructure Behind Remote Work (It’s Not Just Wi-Fi) The Lithography Handbook: Machines, Markets, and the Next Wave of Semiconductor Startups ITCM vs DTCM vs DDR: Embedded Memory Types Explained [Full Handbook] AI Paper Review: Improving Language Understanding by Generative Pre-Training (GPT-1) How to Build a Market Research Copilot with MCP and Python [Full Handbook] How to Build a Scoped Note-Taking API with Django Rest Framework and SimpleJWT The Complete SOC 2 Type II Implementation Handbook for Engineers: A Month-by-Month Roadmap with Real Commands Mastering the JavaScript Event Loop Data Science Insights: Why the Mean Lies When Handling Messy Retail Data How to Build High-Ranking SEO Landing Page How to Query Data in DynamoDB Using .Net How to Unblock Your AI PR Review Bottleneck: A Tech Lead’s Guide to Building a Codebase-Aware Reviewer How to Navigate Microservices as a Frontend Engineer How to Compress PDF Files in the Browser Using JavaScript (Step-by-Step) Stanford's youngest instructor talks InfoSec, AI, and catching cheaters - Rachel Fernandez interview [Podcast #217] Product Experimentation with Propensity Scores: Causal Inference for LLM-Based Features in Python How to Build a Multi-Agent AI System with LangGraph, MCP, and A2A [Full Book] How to Land Your First Cloud or DevOps Role: What Hiring Managers Actually Look For How to Deploy a Serverless Spam Classifier Using Scikit-Learn, AWS Lambda, & API Gateway How to Dockerize a Go Application – Full Step-by-Step Walkthrough Learn Hardware, Cloud, DevOps, Networking, Security, Databases, DNS, Git, and Linux Inside TreeHacks 2026, Stanford’s Elite Student Hakc Inside Stanford’s Elite Student Hackathon [Full Documentary] How to Measure Your AI Citation Rate Across ChatGPT, Perplexity, and Claude How to Deploy a Full-Stack Next.js App on Cloudflare Workers with GitHub Actions CI/CD How to Build a Multi-Tenant SaaS Platform with Next.js, Express, and Prisma How I Completed 15 freeCodeCamp Certifications in 4 Months: A Structured Learning Journey How to Build an Agentic Terminal Workflow with GitHub Copilot CLI and MCP Servers How AI Changed the Economics of Writing Clean Code How to Apply STRIDE Threat Modeling and SonarQube Analysis for Secure Software Development How to Set Up OpenID Connect (OIDC) in GitHub Actions for AWS How to Split PDF Files in the Browser Using JavaScript (Step-by-Step) How to Build Your Own Language-Specific LLM [Full Handbook] How to Build a Self-Learning RAG System with Knowledge Reflection How to Trace Multi-Agent AI Swarms with Jaeger v2 How I Tested Malaysia's Open Data Portals with Plain English How I Built a Production-Ready CI/CD Pipeline for a Monorepo-Based Microservices System with Jenkins, Docker Compose, and Traefik The Hidden Tax of Infrastructure: Why Your Team Shouldn’t Be Running It Anymore From Metrics to Meaning: How PaaS Helps Developers Understand Production From Symptoms to Root Cause: How to Use the 5 Whys Technique Product Experimentation for AI Rollouts: Why A/B Testing Breaks and How Difference-in-Differences in Python Fixes It How to Create a GPU-Optimized Machine Image with HashiCorp Packer on GCP 3D Web Development with Blender and Three.js How to Fix a Failing GitHub PR: Debugging CI, Lint Errors, and Build Errors Step by Step How to Merge PDF Files in the Browser Using JavaScript (Step-by-Step) How to Handle Stripe Webhooks Reliably with Background Jobs How to Build an Automatic Knowledge Graph for Your Blog with PHP and JSON-LD Understanding Proxies and Reverse Proxies: Your Gateway to Secure Networking The Evolution of Nvidia Blackwell GPU Memory Architecture How to Use PostgreSQL as a Cache, Queue, and Search Engine The New Definition of Software Engineering in the Age of AI Reclaim Your Time – Master Automation with Zapier How to Create Dynamic Emails in Go with React Email Why Many Beginner Self-Taught Developers Struggle (And What to Do About It) How to Build a Headless WordPress Frontend with Astro SSR on Cloudflare Pages How to Make Your GitHub Profile Stand Out How to Use Context Hub (chub) to Build a Companion Relevance Engine Why Chrome OS Is the Operating System the AI Era Was Built For How to Build Microservices-Based REST APIs for Healthcare Portals How to friction-max your learning with software engineer Jessica Rose [Podcast #216] Shadow AI Explained: Why Employees Are Using AI Behind Your Back Traditional Scraping vs AI Scraping: A Practical Guide for Developers and Data Teams How Database Indexes Work – A Practical Guide with PostgreSQL Examples How to Streamline Search in Web Applications with Elasticsearch How to Build an Open Source Data Lake for Batch Ingestion OpenAI Codex Essentials – AI Assisted Agentic Development Course Learn Software System Design How to Generate PDF Files in the Browser Using JavaScript (With a Real Invoice Example) How to Get Started with Terraform Service-to-Service Communication: When to Use REST, gRPC, and Event-Driven Messaging A Developer’s Guide to Lazy Loading in React and Next.js The Data Quality Handbook: Data Errors, the Developer's Role, and Validation Layers Explained. United States Residential Proxy: Why Local IP Accuracy Matters for SERP, Ads, and Pricing How to Build a Fashion App That Helps You Organize Your Wardrobe How to Build an Admin Dashboard Sidebar with shadcn/ui and Base UI The AI Governance Handbook: How to Build Responsible AI Systems That Actually Ship How to Build a Local DevOps HomeLab with Docker, Kubernetes, and Ansible How to Use Mixins in Flutter [Full Handbook] How to Prep for Technical Interviews – A Guide for Web Developers GPT-5.4 vs GLM-5: Is Open Source Finally Matching Proprietary AI? Data Visualization Tools for Svelte Developers How to Keep Human Experts Visible in Your AI-Assisted Codebase Efficient Data Processing in Python: Batch vs Streaming Pipelines Explained How to Build and Deploy Multi-Architecture Docker Apps on Google Cloud Using ARM Nodes (Without QEMU) How to Build a Secure AI PR Reviewer with Claude, GitHub Actions, and JavaScript How to Build a Positioning-Based Crude Oil Strategy in Python [Full Handbook] How to learn programming and CS in the AI hype era – interview with dev and prof Mark Mahoney [Podcast #215] CUDA Programming for NVIDIA H100s How to Build Reliable AI Systems. How to Build an Online Marketplace with Next.js, Express, and Stripe Connect How to Build a Cost-Efficient AI Agent with Tiered Model Routing The WebCodecs Handbook: Native Video Processing in the Browser The Bluetooth LE Audio Handbook: From "Why Does My Call Sound Like a Tin Can?" to AOSP Implementation How to Set Up OpenClaw and Design an A2A Plugin Bridge
How to Build a Scalable Design System in a Monorepo
Vineeth Pawar · 2026-06-23 · via freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
How to Build a Scalable Design System in a Monorepo

When you hear "Scalable Design System with a Monorepo Ecosystem" it might sound like a bunch of jargon glued together. Let's simplify:

  • Design system: the building blocks of your product (buttons, inputs, styles, tokens, patterns).

  • Monorepo: one big repo with multiple packages living together, sharing tooling and workflows.

Now here's the magic: when you combine them, you get modularity, consistency, and a faster development cycle. Basically the dream setup for teams working across web, mobile, and beyond.

In this article, you'll learn how to build a modular, scalable design system using React and Turborepo – the same approach used by Microsoft, IBM, and Shopify.

Table of Contents

  • Prerequisites

  • Who's Already Doing This?

  • Why it Works

  • Think of it Like a Ladder

  • The Same Design System, Everywhere

  • Should You Go Monorepo?

  • When a Monorepo Is Not the Right Fit

  • Let's Build Our Design System

    • Create Your Turborepo Project

    • Design Your Package Structure

    • Build Your Design Tokens Package

    • Create Primitive Components

    • Configure the Turborepo Pipeline

    • Build the @yourds Packages

    • Use Your Design System in an App

  • Wrapping Up

Prerequisites

Before you follow along, you'll want to have a few things in place:

  • Working knowledge of React and TypeScript: You should be comfortable creating components and reading basic type annotations.

  • Familiarity with the command line: You'll run npx, npm, and similar commands throughout.

  • Node.js installed (v18 or later): Verify with node -v. If you don't have it, install it from nodejs.org.

  • A package manager: This guide uses npm, but pnpm or yarn will work with minor command tweaks.

  • A code editor of your choice (VS Code is a popular fit for TypeScript work).

You don't need any prior experience with monorepos or Turborepo. We'll set everything up from scratch.

Who's Already Doing This?

Turns out, some of the biggest design systems you've heard of run inside monorepos:

  1. Microsoft Fluent UI: lives in a multi-package monorepo that ships React components, Web Components, and even design tokens.

  2. IBM Carbon: multiple packages like @carbon/ibm-products come straight out of their Carbon monorepo.

  3. Shopify Polaris: openly describes itself as a monorepo, packaging React components, docs, and even a VS Code extension.

  4. Atlassian Atlaskit: their public @atlaskit/* packages are published from a large internal monorepo.

  5. MUI (Material UI): maintained as a mono-repository to coordinate React components, tooling, and docs.

  6. Elastic EUI: developed and released from a single repo, with discussions about monorepo publishing flows.

Why it Works

When you put all the pieces of your design system in one repository, you get a few specific advantages that are hard to replicate in a split-repo setup. Each of these reinforces the others, which is why teams that adopt this pattern rarely go back.

Here's what makes it work:

  • Consistency: tokens, styles, and primitives are defined once and flow everywhere.

  • Faster iteration: fix a bug in Button and the updates cascade to mobile, desktop, and docs instantly.

  • Shared tooling: linting, tests, CI pipelines, and release workflows are configured once, and then applied to all packages.

  • Versioning control: with tools like Changesets or Lerna, you can release packages independently but keep them aligned.

  • Cross-platform flexibility: the same building blocks can power React web apps, React Native, Electron apps, SDKs, and documentation sites.

Think of it Like a Ladder 🪜

The cleanest way to picture a monorepo design system is as a series of stacked layers. Each layer builds on the one beneath it, and each layer has a clear job.

New contributors find their way around faster because the relationships between packages are predictable: tokens flow up into primitives, primitives compose into layouts, and layouts assemble into screens.

The diagram below shows this stack visually:

Layered architecture of a monorepo design system: design tokens at the base, then plugins (utility helpers), then layouts, then screens, then navigators at the top, with the app shell consuming a single package that pulls all layers together

At the base, you've got primitives (tokens, styles).

Above that: plugins (utility helpers).

Then come layouts, built from plugins + primitives.

Then screens, built from layouts.

Finally, navigators tie screens together.

At the very top: your app imports just one package, and boom! The UI is environment-agnostic.

The Same Design System, Everywhere

The real payoff of this ladder is that you climb it once, then reuse the whole thing across every platform you ship to.

A button defined in your primitives package can render in a web app, a React Native mobile app, an Electron desktop app, or a documentation site without you rewriting it for each environment.

The diagram below shows the same design system flowing into three different app types, with each environment importing the same package and getting consistent styling, behaviour, and accessibility out of the box:

The same design system feeding three different apps from a single import: a web application on a browser, a desktop application in an Electron-style window, and a mobile application on a phone screen. Each app pulls from the shared primitives and tokens packages, ensuring buttons, typography, and spacing look and behave the same everywhere

Whether it's web, desktop, or mobile, the design system climbs that same ladder.

Should You Go Monorepo?

Not every team needs one. But if you're building a design system that's meant to serve multiple apps, stay consistent across platforms, and support lots of contributors, then a monorepo becomes less of a buzzword and more of a sanity-saver.

When a Monorepo Is Not the Right Fit

A quick clarification first, because monorepos sometimes get tangled up with another debate. The "monorepo vs polyrepo" question is not the same as the "monolith vs microservices" question. You can absolutely run microservices out of a monorepo (Google and Facebook do this at massive scale).

The two choices live on different axes: monorepo vs polyrepo is about where the code lives, while monolith vs microservices is about how the runtime is shaped.

With that out of the way, here are a few signs a monorepo may not be the best fit for your situation:

  • You're a small team shipping a single product. The tooling overhead of a monorepo (workspace config, build pipelines, package boundaries) may slow you down more than it helps. A single React app with no shared libraries probably doesn't need this layer.

  • Your packages have wildly different release cadences and stakeholders. If two parts of your codebase are owned by teams that need very different deploy pipelines, governance, or security postures, separate repos can reduce friction.

  • You can't invest in monorepo tooling. Tools like Turborepo, Nx, and Changesets do a lot of heavy lifting, but they have a learning curve. If your team can't dedicate time to set them up and maintain them, you may struggle.

  • You're using languages or runtimes that don't share well. Monorepos shine when most packages live in the same toolchain. Mixing Node, Go, Rust, and Python in one repo is possible, but the build-tool story gets harder.

For most teams building a serious design system, none of these are dealbreakers. But it's worth checking your situation before committing.

Let's Build Our Design System

Create Your Turborepo Project

Start by creating a new Turborepo project. This gives you the perfect foundation for a scalable monorepo.

# Create a new Turborepo project
npx create-turbo@latest my-design-system

# Navigate to the project
cd my-design-system

# Install dependencies
npm install

Turborepo creates a workspace with apps/ and packages/ folders, shared tooling configuration, and optimized build pipelines.

Design Your Package Structure

Next, create a logical hierarchy for your design system packages. Think of it like a ladder, as I mentioned above: each level builds on the one below.

my-design-system/
├── packages/
│   ├── tokens/          # Design tokens (colors, spacing, typography)
│   ├── primitives/      # Base components (Button, Input, Card)
│   ├── layouts/         # Layout components (Grid, Stack, Container)
├── apps/
│   ├── web/            # Example web app
│   └── docs/           # Documentation site
└── turbo.json          # Turborepo configuration

Detailed file structure

my-design-system/
├── packages/
│   ├── tokens/
│   │   ├── src/
│   │   │   ├── colors.ts
│   │   │   ├── spacing.ts
│   │   │   ├── typography.ts
│   │   │   └── index.ts
│   │   ├── package.json
│   │   └── tsconfig.json
│   ├── primitives/
│   │   ├── src/
│   │   │   ├── Button/
│   │   │   │   └── Button.tsx
│   │   │   ├── Input/
│   │   │   │   └── Input.tsx
│   │   │   └── index.ts
│   │   ├── package.json
│   │   └── tsconfig.json
│   ├── layouts/
│   │   ├── src/
│   │   │   ├── Grid/
│   │   │   ├── Stack/
│   │   │   └── index.ts
│   │   └── package.json
├── apps/
│   ├── web/
│   │   ├── src/
│   │   │   ├── App.tsx
│   │   │   └── main.tsx
│   │   ├── index.html
│   │   └── package.json
│   └── docs/
│       ├── src/
│       └── package.json
├── turbo.json
├── package.json
└── README.md

Build Your Design Tokens Package

Start with the foundation: design tokens. Tokens are the smallest, most reusable units of a design system: a color value, a spacing step, a font size, a border radius. Instead of hard-coding padding: 16px or color: #3b82f6 everywhere, you reference a token like spacing.md or colors.primary[500].

The benefits are huge:

  • One place to change a value: update a token once and every component that uses it updates automatically.

  • Theming becomes trivial: want a dark mode? Just swap which tokens resolve to which values.

  • Cross-platform consistency: the same token names work in web CSS, native styles, even Figma.

Tokens are the DNA of your design system. Let's build them.

# Create the tokens package
mkdir -p packages/tokens/src
cd packages/tokens

Update these in your packages/tokens/package.json. This file declares the package name, version, build scripts, and dev dependencies needed to compile the token source files into a publishable package:

{
  "name": "@yourds/tokens",
  "version": "1.0.0",
  "main": "dist/index.js",
  "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"
  },
  "devDependencies": {
    "tsup": "^8.0.0",
    "typescript": "^5.0.0"
  }
}

Update these in your packages/tokens/src/colors.ts. This file defines the color tokens: a named palette of color values organised by intent (primary, gray) and shade (50 is lightest, 900 is darkest). Components reference these by name rather than hardcoding hex codes:

export const colors = {
  primary: {
    50: '#f0f9ff',
    100: '#e0f2fe',
    500: '#3b82f6',
    600: '#2563eb',
    900: '#1e3a8a'
  },
  gray: {
    50: '#f9fafb',
    100: '#f3f4f6',
    500: '#6b7280',
    900: '#111827'
  }
} as const;

Update these in your packages/tokens/src/spacing.ts. This file defines the spacing scale: a set of standard size steps that components use for padding, margin, and gap values. Using a fixed scale (xs, sm, md, lg, and so on) keeps spacing consistent across the UI:

export const spacing = {
  xs: '0.25rem',    // 4px
  sm: '0.5rem',     // 8px
  md: '1rem',       // 16px
  lg: '1.5rem',     // 24px
  xl: '2rem',       // 32px
  '2xl': '3rem'     // 48px
} as const;

Update these in your packages/tokens/src/typography.ts. This file defines the typography tokens: font sizes and font weights that components use for text. Like spacing, these are named steps rather than arbitrary pixel values:

export const typography = {
  fontSizes: {
    xs: '0.75rem',
    sm: '0.875rem',
    base: '1rem',
    lg: '1.125rem',
    xl: '1.25rem',
    '2xl': '1.5rem'
  },
  fontWeights: {
    normal: 400,
    medium: 500,
    semibold: 600,
    bold: 700
  }
} as const;

Update these in your packages/tokens/src/index.ts. This file is the public entry point of the package: it re-exports everything from the three token files so consumers can do import { colors, spacing, typography } from "@yourds/tokens" in a single line:

export * from './colors';
export * from './spacing';
export * from './typography';

Create Primitive Components

Build your base components that consume the design tokens:

# Create the primitives package
mkdir -p packages/primitives/src
cd packages/primitives

# Install dependencies
npm install react react-dom

Update these in your packages/primitives/package.json:

{
  "name": "@yourds/primitives",
  "version": "1.0.0",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "scripts": {
    "build": "tsup src/index.ts --format cjs,esm --dts --external react",
    "dev": "tsup src/index.ts --format cjs,esm --dts --external react --watch"
  },
  "peerDependencies": {
    "react": "^18.0.0",
    "react-dom": "^18.0.0"
  },
  "devDependencies": {
    "@types/react": "^18.0.0",
    "tsup": "^8.0.0",
    "typescript": "^5.0.0"
  }
}

Update these in your packages/primitives/src/Button/Button.tsx:

import React from 'react';
import { colors, spacing } from '@yourds/tokens';

interface ButtonProps {
  variant?: 'primary' | 'secondary' | 'outline';
  size?: 'sm' | 'md' | 'lg';
  children: React.ReactNode;
  onClick?: () => void;
  disabled?: boolean;
}

export const Button: React.FC<ButtonProps> = ({
  variant = 'primary',
  size = 'md',
  children,
  disabled = false,
  ...props
}) => {
  const baseStyles = {
    border: 'none',
    borderRadius: '0.5rem',
    cursor: disabled ? 'not-allowed' : 'pointer',
    fontWeight: 500,
    transition: 'all 0.2s ease',
    opacity: disabled ? 0.6 : 1
  };

  const variants = {
    primary: {
      backgroundColor: colors.primary[500],
      color: 'white',
      ':hover': { backgroundColor: colors.primary[600] }
    },
    secondary: {
      backgroundColor: colors.gray[100],
      color: colors.gray[900],
      ':hover': { backgroundColor: colors.gray[200] }
    },
    outline: {
      backgroundColor: 'transparent',
      color: colors.primary[500],
      border: `1px solid ${colors.primary[500]}`,
      ':hover': { backgroundColor: colors.primary[50] }
    }
  };

  const sizes = {
    sm: { padding: `\({spacing.xs} \){spacing.sm}`, fontSize: '0.875rem' },
    md: { padding: `\({spacing.sm} \){spacing.md}`, fontSize: '1rem' },
    lg: { padding: `\({spacing.md} \){spacing.lg}`, fontSize: '1.125rem' }
  };

  const buttonStyle = {
    ...baseStyles,
    ...variants[variant],
    ...sizes[size]
  };

  return (
    <button style={buttonStyle} disabled={disabled} {...props}>
      {children}
    </button>
  );
};

Update these in your packages/primitives/src/index.ts:

export { Button } from './Button/Button';
export type { ButtonProps } from './Button/Button';

Configure the Turborepo Pipeline

Now, set up the build pipeline in turbo.json to ensure packages build in the correct order.

{
  "$schema": "https://turbo.build/schema.json",
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**"]
    },
    "dev": {
      "cache": false,
      "persistent": true
    },
    "lint": {},
    "type-check": {
      "dependsOn": ["^build"]
    }
  }
}

Build the @yourds Packages

With the tokens and primitives packages defined, the next step is to compile them so they can be consumed by your apps.

Running npm install at the root resolves all workspace dependencies, including the internal links between @yourds/tokens and @yourds/primitives. Then npm run build walks through every package and runs each one's build script, which Turborepo orders correctly so tokens compiles before primitives (since primitives depend on tokens). The final npm install step then registers the built packages so your apps/web app can import them by name:

# Go to the root of the monorepo
npm install

# Compile every package in the right order
npm run build

# Register the built packages for the apps to use
npm install @yourds/tokens @yourds/primitives

If everything ran successfully, you should see a dist/ folder inside both packages/tokens and packages/primitives, containing compiled JavaScript and TypeScript declaration files.

Use Your Design System in an App

Now you can consume your design system in any React application.

The example below replaces the default content in your apps/web/src/App.tsx file with a small home page that demonstrates two things at once: importing primitives (the Button component) from @yourds/primitives, and importing tokens (colors, spacing) directly from @yourds/tokens to style standard HTML elements like the wrapper <div> and the <h1>.

The result is a fully working page that uses your design system end-to-end, with zero hardcoded colors or spacing values:

import { Button } from "@yourds/primitives";
import { colors, spacing } from "@yourds/tokens";

export default function Home() {
  return (
    <div style={{ padding: spacing.lg }}>
      <h1 style={{ color: colors.primary[500] }}>My App with Design System</h1>
      <Button variant="primary" size="lg">
        Get Started
      </Button>
      <Button variant="outline" size="md">
        Learn More
      </Button>
    </div>
  );
}

Once you save the file, run the app in development mode:

npx turbo dev --filter=web

You should see your home page render with the primary[500] blue heading, padded by spacing.lg, and two buttons styled by your shared design system. Any change you make to a token (say, swapping the primary color) will flow into this page automatically the next time you rebuild.

Wrapping up

A monorepo won't magically make your design system perfect. But it does give you:

  • A shared space where everything connects

  • The agility to publish parts independently

  • The clarity to scale design across teams and platforms

No wonder the biggest design systems in the world are already doing it.



Learn to code for free. freeCodeCamp's open source curriculum has helped more than 40,000 people get jobs as developers. Get started