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.