UIUpdated August 3, 2026

Installation

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

UIInstallation

Install the primitive layer firstLink to section

@pycolors/ui is the public primitive package for PyColors product interfaces. Install it when you want reusable React primitives for SaaS surfaces such as forms, settings, dashboards, billing panels, overlays, and data views.

Core idea

Install the package, load the semantic token CSS your app needs, import from @pycolors/ui, then verify one small screen before migrating more UI.

PrerequisitesLink to section

Before installing, confirm the consuming app already has:

  • React and React DOM installed;
  • Tailwind CSS available 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 @pycolors/ui with your package manager.

pnpm add @pycolors/ui
npm i @pycolors/ui
yarn add @pycolors/ui

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

Use @pycolors/tokens when your app does not already provide the PyColors semantic variables and Tailwind v4 mappings.

pnpm add @pycolors/tokens
npm i @pycolors/tokens
yarn add @pycolors/tokens

Import the token CSS once from your global stylesheet.

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

In the PyColors marketing app, this is done from apps/marketing/app/global.css.

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 at the app shell or document root through your existing theme logic.

Import from the public entry pointLink to section

Import supported primitives from @pycolors/ui.

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

export 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="/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 consuming app’s type check and build command. In this monorepo, the relevant docs app check is:

pnpm --filter pycolors-marketing 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.
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