Shared components and styles for all kits.
ui (packages/ui) is the shared foundation for Feature Kits: primitives, semantic tokens, and global styles that form, data-table, layout, and uploader compose. It is not a replacement for those workflow kits.
When to use it
- Adding a new primitive (button variant, dialog, field shell) shared across kits
- Theming the host app via
ui/globals.cssCSS variables - Importing low-level controls when a kit does not expose a higher-level API
Prefer kit components (FormKit.Field, table toolbar pieces) before pulling raw UI into product screens—kits encode spacing, i18n, and accessibility patterns.
Installation
Apps in this monorepo reference UI through TypeScript paths (see apps/web/tsconfig.json):
import { Button } from "@/packages/ui/components/button"
import { cn } from "@/packages/ui/lib/utils"Load global styles once in the app root:
/* apps/web/src/app/globals.css */
@import "ui/globals.css";Feature kits depend on packages/ui as a workspace package; you do not publish UI separately when working inside the monorepo.
For an application integration checklist, see Installation.
Structure
| Area | Location |
|---|---|
| Components | packages/ui/src/components/* |
| Utilities | packages/ui/src/lib/utils.ts (cn, etc.) |
| Theme | packages/ui/src/globals.css |
| Icons | Lucide via kit components |
Components follow the same patterns as shadcn/ui: Radix primitives, class-variance-authority variants, and Tailwind v4 tokens.
Usage patterns
Buttons & inputs
Kits re-use Button, Input, Select, Dialog, Table, and field shells from UI. When extending a kit, match existing variant names (outline, ghost, destructive) so tables and forms stay aligned.
Theming
CSS variables in globals.css define semantic roles such as --background, --foreground, --primary, and sidebar/chart tokens. next-themes toggles light/dark at the app level (apps/web/src/app/providers.tsx).
Use roles rather than hard-coding a color in a feature component:
| Token role | Used for | Example |
|---|---|---|
background | Application surfaces | Page body |
foreground | Primary text | Headings |
muted | Secondary content | Descriptions |
border | Separation | Cards and tables |
primary | Main action | Submit button |
destructive | Dangerous action | Delete |
Override tokens at the application theme layer when your product needs a different visual language. Keep shared roles consistent so feature kits retain readable states in both modes.
Adding a component
- Scaffold the primitive under
packages/ui/src/components/. - Export from the package if other features need it.
- Reference it from a feature kit instead of from app code when the control is reusable.
Composition rules
- Use a feature kit when it owns a workflow state or repeated interaction.
- Use a UI primitive for a local control or a small visual composition.
- Add a local wrapper when the composition is specific to one product domain.
- Contribute a primitive to
uionly when multiple feature packages need the same behavior.
Relationship to kits
flowchart TB
ui[packages/ui]
form[form]
table[data-table]
layout[layout]
uploader[uploader]
ui --> form
ui --> table
ui --> layout
ui --> uploaderGotchas
Path aliases
The docs site uses @/packages/ui/.... Your app may use a different alias—keep imports consistent within each app.
Do not fork styles per kit
One globals.css import per app. Kits assume shared tokens; duplicating theme files causes drift between tables and forms.
For component-level docs, browse packages/ui/src/components and the live previews under Form and Data table.