Proper UI

Monorepo integration

Consume Proper UI from a Turborepo or pnpm workspace — the workspace protocol, Tailwind source scanning, and TypeScript project references.

If you already run Proper UI's own monorepo layout — a pnpm workspace with apps/* and packages/* — or you're adding it to one of yours, @properui/ui behaves exactly like a published npm package, resolved locally instead of from the registry.

Installation

List the package as a workspace dependency of whichever app consumes it:

// apps/web/package.json
{
    "dependencies": {
        "@properui/ui": "workspace:*"
    }
}

pnpm-workspace.yaml (or the workspaces field in package.json for npm/Yarn) needs to include both the app and the package:

# pnpm-workspace.yaml
packages:
    - "apps/*"
    - "packages/*"

Run pnpm install and pnpm symlinks packages/ui into apps/web/node_modules/@properui/ui — from the app's point of view it's an ordinary dependency, so the same next.config.ts and CSS setup from the Next.js guide or Vite guide applies without changes:

// apps/web/next.config.ts
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
    transpilePackages: ["@properui/ui"],
};

export default nextConfig;
/* apps/web/app/globals.css */
@import "@properui/ui/styles/globals.css";

@source "../node_modules/@properui/ui/src/**/*.{ts,tsx}";

For editor tooling and incremental builds, add a TypeScript project reference from the app to the package so tsc --build understands the dependency order:

// apps/web/tsconfig.json
{
    "references": [{ "path": "../../packages/ui" }]
}
// packages/ui/tsconfig.json
{
    "compilerOptions": {
        "composite": true
    }
}

Custom alias paths

Inside packages/ui/src, every component imports its neighbors with the package's own @/ alias — that alias is local to the package and resolves against packages/ui/src, never against your app's src directory. Leave it alone; the CLI rewrites it automatically when it copies a component into a project that doesn't use the workspace package.

Your app keeps its own @/ alias pointing at its own src, and reaches Proper UI through the package's subpath exports instead of reusing that alias for the shared package:

// apps/web/tsconfig.json
{
    "compilerOptions": {
        "paths": {
            "@/*": ["./src/*"]
        }
    }
}

If you want to jump straight to the package's source while developing — skipping the built output — add a second alias that points at it explicitly:

// apps/web/tsconfig.json
{
    "compilerOptions": {
        "paths": {
            "@/*": ["./src/*"],
            "@properui/ui/*": ["../../packages/ui/src/*"]
        }
    }
}

This is a development convenience only — published consumers outside the monorepo always resolve @properui/ui/* through the package's own exports map, so keep the mapping scoped to apps that live inside this workspace.

FAQs