Installation

Install @pycolors/ui, load the token CSS, and verify your first public import in a React or Next.js app.

UIUpdated October 7, 2026

Install the primitive layer firstLink to section

This guide takes you from an existing React app to a styled PyColors component. You will install the packages, connect the CSS, and verify a small screen in your own app.

PrerequisitesLink to section

Before installing, confirm the consuming app already has:

  • React and React DOM installed;
  • Tailwind CSS v4 configured in the app stylesheet/build;
  • a global stylesheet where token CSS can be imported;
  • a React or Next.js setup that supports ESM packages.

@pycolors/ui is Tailwind-friendly and token-driven. Components use semantic utilities such as bg-card, text-muted-foreground, border-border, and ring-ring. Those utilities need matching design tokens in the consuming app.

Install packagesLink to section

Install the public primitives and their semantic tokens together. This is the canonical first-install command for a pnpm project.

Terminal
pnpm add @pycolors/ui @pycolors/tokens

Use the equivalent npm install or yarn add command when the app does not use pnpm. Keep both package names in the command so the components and their token contract arrive together.

Peer dependenciesLink to section

@pycolors/ui declares these peer dependencies:

PackageRequirementNotes
react>=18Required by the React primitives.
react-dom>=18Required for React DOM apps.
lucide-react>=0.300.0Optional peer dependency. Install it when your app or examples use Lucide icons.

The package README documents this install command for peer dependencies:

pnpm add react react-dom lucide-react

Use the equivalent npm or yarn command when the app does not use pnpm.

Add design tokensLink to section

The canonical install command above includes @pycolors/tokens. Use its token CSS when your app does not already provide the PyColors semantic variables and Tailwind v4 mappings.

In a Next.js app with an app/ directory at the project root, add the following to your global stylesheet and import that stylesheet from app/layout.tsx. Keep any existing app styles after these directives.

app/globals.css
@import "tailwindcss";
@import "@pycolors/tokens/tokens.css";

@source "../node_modules/@pycolors/ui/dist";
@custom-variant dark (&:where(.dark, .dark *));

@layer base {
  * {
    @apply border-border;
  }

  body {
    @apply bg-background text-foreground;
  }
}

Tailwind ignores node_modules during automatic source detection. The @source directive includes the installed component classes so their utilities are generated. This is a CSS scan path; JavaScript imports still use only @pycolors/ui.

The path is relative to the stylesheet. For src/app/globals.css, use ../../node_modules/@pycolors/ui/dist instead. In other React setups, adjust the path to reach the consuming app's installed package and load this stylesheet from the app's entry point. Do not add a second Tailwind import if one already exists.

The base rules apply the semantic border and page colors. Merge them with your existing base styles if the app already sets those roles.

The token CSS provides:

  • semantic CSS variables such as --background, --foreground, --card, --primary, --border, and --ring;
  • light and dark values using a .dark class strategy;
  • Tailwind v4 @theme inline mappings for semantic utilities.

Dark mode

@pycolors/tokens uses a .dark class strategy. Add or remove the dark class on the document root through your existing theme logic. The @custom-variant directive makes Tailwind's dark: utilities follow that same class.

Verify components in StorybookLink to section

Use the consumer Storybook guide to render PyColors in your own React/Vite Storybook with tokens, generated Tailwind utilities, and a light/dark toolbar. For examples without local setup, open PyColors UI Explorer.

Import from the public entry pointLink to section

Import supported primitives from @pycolors/ui.

In the same Next.js app, use this page to verify the installation. Other React apps can render the exported component from their existing route or entry point.

app/page.tsx
import {
  Button,
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@pycolors/ui";

export default function FirstPyColorsCard() {
  return (
    <Card>
      <CardHeader>
        <CardTitle>PyColors UI installed</CardTitle>
        <CardDescription>
          Your app can now compose token-driven product primitives.
        </CardDescription>
      </CardHeader>
      <CardContent>
        <Button asChild>
          <a href="https://pycolors.io/docs/ui/usage-patterns">
            Explore usage patterns
          </a>
        </Button>
      </CardContent>
    </Card>
  );
}

Do not import from package internals.

Prefer

  • imports from @pycolors/ui
  • semantic token utilities such as bg-card and text-muted-foreground
  • one verified screen before a broad migration

Avoid

  • imports from @pycolors/ui/src/*
  • imports from @pycolors/ui/dist/*
  • raw color overrides that bypass tokens

Server and client component boundariesLink to section

Static primitive composition can stay server-rendered in a Next.js App Router app. Add "use client" only when the file owns browser state, effects, event handlers, or interactive overlay/toast state.

server-safe-card.tsx
import { Button, Card, CardContent, CardHeader, CardTitle } from "@pycolors/ui";

export function BillingCard() {
  return (
    <Card>
      <CardHeader>
        <CardTitle>Billing ready</CardTitle>
      </CardHeader>
      <CardContent>
        <Button asChild>
          <a href="/settings/billing">Manage billing</a>
        </Button>
      </CardContent>
    </Card>
  );
}

Use a client boundary for local interaction state.

client-action.tsx
"use client";

import { Button } from "@pycolors/ui";

export function SaveButton() {
  return (
    <Button type="button" onClick={() => window.alert("Saved")}>
      Save
    </Button>
  );
}

Boundary rule

Keep pages and data loading server-side when possible. Move only the interactive leaf into a client component.

Verify the first screenLink to section

Confirm the app buildsLink to section

Run the type-check and production-build scripts declared in your consuming app's package.json. For example, when it defines types:check and build:

pnpm types:check
pnpm build

Check token outputLink to section

Open the screen in light and dark mode. Confirm semantic utilities such as bg-card, text-foreground, border-border, and ring-ring resolve to real styles.

Check accessibility basicsLink to section

Tab through interactive elements, verify visible focus, confirm links have descriptive text, and avoid color-only feedback.

Expand one surface at a timeLink to section

After the first screen works, move to usage patterns and migration guidance before replacing a full product area.

Common mistakesLink to section

MistakeSafer path
Importing from @pycolors/ui/src/* or @pycolors/ui/dist/*Import from @pycolors/ui.
Installing UI without token CSS or equivalent semantic variablesLoad @pycolors/tokens/tokens.css or provide the same semantic roles intentionally.
Components render without spacing or variant stylesRegister the installed UI package with @source, using a path relative to the global stylesheet.
Adding "use client" to every pageAdd a client boundary only where browser behavior is owned.
Replacing product logic with UI primitivesKeep routing, auth, billing, validation, and data fetching in app code.
Styling with raw colors firstUse semantic utilities and customize tokens centrally when needed.

Next stepsLink to section