Tailwind Config for Monorepo Projects

Share Tailwind CSS configuration across monorepo packages with a preset-based approach, shared content paths, and consistent theme tokens.

Framework

Detailed Explanation

Tailwind in Monorepos

Monorepos (Turborepo, Nx, PNPM workspaces) need a strategy for sharing Tailwind config across packages.

The Preset Approach

Create a shared config package:

packages/
  tailwind-config/
    tailwind.config.js   <- shared preset
    package.json
  ui/
    tailwind.config.js   <- extends preset
  web/
    tailwind.config.js   <- extends preset

Shared Preset

// packages/tailwind-config/tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        brand: "#1a73e8",
        accent: "#ff6b35",
      },
      fontFamily: {
        sans: ["Inter", "ui-sans-serif", "system-ui"],
      },
    },
  },
  plugins: [
    require("@tailwindcss/typography"),
  ],
};

Consuming the Preset

// apps/web/tailwind.config.js
const sharedConfig = require("@acme/tailwind-config");

module.exports = {
  presets: [sharedConfig],
  content: [
    "./app/**/*.{js,ts,jsx,tsx}",
    "./components/**/*.{js,ts,jsx,tsx}",
    // Include shared UI package
    "../../packages/ui/src/**/*.{js,ts,jsx,tsx}",
  ],
};

Content Path Scanning

The biggest gotcha in monorepos is content paths. Each app must scan:

  1. Its own source files
  2. Any shared packages that use Tailwind classes

Turborepo with Tailwind

In turbo.json, ensure tailwind.config.js is part of your build inputs:

{
  "pipeline": {
    "build": {
      "inputs": ["src/**", "tailwind.config.*", "postcss.config.*"]
    }
  }
}

Tips

  • Keep the preset minimal -- only shared design tokens
  • Let each app extend for app-specific customization
  • Use CSS variables for values that change between apps

Use Case

Use this approach when you have multiple applications or packages in a monorepo that need to share a consistent Tailwind design system.

Try It — Tailwind Config Builder

Open full tool