prime-ui-kit
v0.37.1
Published
React 19 UI kit for product interfaces: 82 composable components on one design contract — forms, selects, tables, overlays, navigation, app shell. CSS Modules, --prime-* tokens, light and dark themes, TypeScript, a11y, Next.js App Router ready. Ships COMP
Maintainers
Keywords
Readme
prime-ui-kit
A calm, precise React 19 UI kit for product interfaces — admin panels, dashboards, settings, forms and data tables. 82 components on one design contract, one API vocabulary and one set of tokens, so every screen you build looks like it was drawn by the same hand.
- Graphite design language. Depth from fill, not lines — a surface ladder where every nested
layer and every control is one lightness step off its host; a strict 4px grid; one size axis
xs · s · m · l · xlwhere a Button, an Input and a Select of the same size line up to the pixel; air as hierarchy. - Light and dark as equals. Full themes, WCAG AA text contrast, a focus ring that is never clipped.
- One API everywhere.
size,variant,tone,color,invalid/hint/error,value/onValueChange,checked/onCheckedChange,open/onOpenChange,labels— the same names in every component, compound partsX.Root+X.Partfor components with parts and a single export for leaves (<Kbd>,<Divider>), state indata-*. - Built from itself. Components reuse the kit's own Button, Badge, Spinner, Icon, Checkbox, EmptyPage and ScrollContainer instead of private copies, so a fix in one place lands everywhere.
- States flow, they never flip. Controls move into their new state; a region that switches
between loading, data, empty and error cross-fades, opacity only, at its new height at once
(
Crossfade), and while it loads aSkeletonholds the shape of the coming content — so nothing on the page jumps. - Overlays that behave. Modal, Drawer, Sheet, Popover, Dropdown, Select, Tooltip, CommandMenu and MediaViewer share one stack: one click or one Escape closes exactly the topmost layer, focus goes where it should.
- Accessible by default. Keyboard support, ARIA roles, Russian default strings for every system
label,
prefers-reduced-motionandprefers-contrastrespected. - Docs for humans and agents. Every component ships a full
COMPONENT.mdreference and copyableexamples/inside the npm package, together with an agent skill that teaches an AI to build screens the way the kit's author would.
Links: npm · Repository & issues · Design contract
Use with AI assistants
prime-ui-kit is built to be used by coding agents (Claude Code, Cursor, Codex, …) as well as people:
- Install the agent skill — it teaches the agent the design rules, the API and page recipes.
It ships in the package:
npx prime-ui-kit skill(details). - The docs are already on disk. Every component ships
COMPONENT.md(full API, variants, states, a11y, mistakes) and copyableexamples/*.tsxinnode_modules/prime-ui-kit/src/components/<name>/, matching the installed version. - Ask for screens in plain words — "build an orders list with filters and a table", "review this page against the design system". The skill makes the agent pick kit components, apply the spacing scale, wire every state and run a checklist before handing the screen over.
Install
npm install prime-ui-kit react react-dom date-fns
# using ColorPicker or ColorField: also react-aria-components
# or: pnpm add … · bun add …| Peer dependency | Version |
|---|---|
| react, react-dom | ^19.0.0 |
| date-fns | ^4.0.0 |
| react-aria-components (optional, only for prime-ui-kit/color-picker) | ^1.16.0 |
The kit has no runtime dependencies, only the peers above: its icons are drawn in (from Lucide), and
createIcon wraps any SVG component you bring (a lucide-react glyph, an SVGR import). It has no
router dependency either: pass your router's
pathname to AppShell.Template scrollResetKey and use asChild for router links.
Set up styles and theme
import "prime-ui-kit/fonts.css"; // optional: Golos Text + JetBrains Mono, metric-matched fallbacks
import "prime-ui-kit/reset.css"; // optional: minimal document reset (skip if the app has its own)
import { applyTheme } from "prime-ui-kit";
applyTheme("dark"); // sets data-theme on <html> without a transition flashThe styles come with the code: prime-ui-kit brings the tokens, both themes and the base rules
(focus ring, reduced motion), and every component imports its own CSS. Your bundler (Vite, webpack,
Next.js, esbuild) keeps only the modules and the styles of the components you use — a screen of a
few controls ships a few controls, not the whole kit. The base leaves the root font size to the
browser. data-theme="light" | "dark" also works on any wrapper, so one page can show both themes.
Focus rings are off by default: Tab still moves focus, but no ring is drawn. One attribute turns every ring of the kit on — buttons, fields, selects, tabs, rows:
<html data-focus-ring="visible">It works on any wrapper too, for one part of a page.
fonts.css loads the faces from Google Fonts. Offline or under a strict CSP (default-src 'self'
in a desktop app) leave it out and self-host them with @fontsource/golos-text (400, 500, 600) and
@fontsource/jetbrains-mono (400, 500) — the token stacks find them by family name — or keep the
system font.
Tests that run the kit in Node need its CSS imports handled: in Vitest, inline the package
(test.server.deps.inline: ["prime-ui-kit"]); in Jest, map \.css$ to a stub with
moduleNameMapper.
Next.js (App Router)
Every module of the package starts with "use client" (the entry files are plain re-exports, as
Next.js asks of a client boundary): importing the kit never pulls React state into the server
graph, and you need no re-export wrapper files. The styles arrive with the components; set the
theme on <html> in the root layout; applyTheme is for switching it later from a client
component.
// app/layout.tsx
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="ru" data-theme="light">
<body>{children}</body>
</html>
);
}Build screens in your own "use client" files and render those from pages and layouts. A server
component itself can render only single-export components with serializable props
(<Typography>, <Spinner>, <Skeleton>): React does not allow dotting into a client module on the
server, so compound parts (<Button.Root>, <Modal.Content>) and any callback prop
(onValueChange, renderX) need a client file. The whole package is client code, helpers
included — call groupMessages, formatMessageDate, applyTheme and the hooks only from client
components.
Quick start
import { AppShell, Button, Icon, Input, Page, Sidebar } from "prime-ui-kit";
export function App() {
return (
<AppShell.Template
nav={
<Sidebar.Root>
<Sidebar.Content>
<Sidebar.Item href="/clients" current>
<Sidebar.ItemIcon>
<Icon name="object.users" />
</Sidebar.ItemIcon>
Клиенты
</Sidebar.Item>
</Sidebar.Content>
</Sidebar.Root>
}
>
<Page.Root>
<Page.TopBar>
<Page.Heading>
<Page.Title>Новый клиент</Page.Title>
</Page.Heading>
</Page.TopBar>
<Page.Body>
<Input.Root label="Рабочая почта" required hint="Отправим на неё приглашение">
<Input.Wrapper>
<Input.Field type="email" placeholder="[email protected]" />
</Input.Wrapper>
</Input.Root>
<Button.Root>Пригласить клиента</Button.Root>
</Page.Body>
</Page.Root>
</AppShell.Template>
);
}Rules of use
Short rules that keep code correct — for people and for AI coding assistants:
- Import everything from the package root:
import { Button, Input } from "prime-ui-kit". The one exceptions areimport { ColorField, ColorPicker } from "prime-ui-kit/color-picker"and the full glyph set,import { BellIcon } from "prime-ui-kit/icons". - Import no kit stylesheet: the styles come with the components. Only the optional
fonts.cssandreset.cssgo to the app root, once. - Compound components are used through parts:
<Button.Root>,<Modal.Root>+<Modal.Content>.<Button>alone is not a component. - Default
sizeism; controls in one row share one size. - Style your own layout with CSS Modules and
--prime-*tokens only — no raw px/hex, no inline styles, no overrides of kit classes. - Before using a component, read its
COMPONENT.md; copy structure from itsexamples/.
How the kit is designed
| Rule | In practice |
|---|---|
| Tokens only | Components read semantic variables --prime-* (--prime-space-4, --prime-color-text-secondary, --prime-control-m-height). Your own CSS uses the same tokens. |
| Fill, not lines | Surfaces stand on one ladder: the page and four nested layers, one OKLab lightness step apart, computed at build time. Light: gray page, white card, deeper layers alternate. Dark: a near-black page, every layer a step lighter. A field, chip or neutral button is one step off the layer it sits on, so nothing merges; controls have no visible outline. |
| Proximity | label → field 4–8 · tile → tile 16 · field → field 20 · block → block 24 · group → group 32 · section → section 40–48. |
| One size axis | size is xs · s · m · l · xl (28 · 32 · 36 · 40 · 48), default m. |
| Semantic vs decorative color | tone carries meaning (danger for destructive), color is a palette hue for badges, tags and avatars. |
The full contract lives in docs/foundation.md.
Components
Every link opens the full reference: anatomy, every prop with its default, every variant, states, accessibility, examples and common mistakes.
Foundations (foundations)
| Component | What it is for | |---|---| | Typography | Text roles of the Golos Text type scale applied to any text element, with reading-width guidance. |
Actions (actions)
| Component | What it is for | |---|---| | Button | A button for explicit actions, with variants, tones, sizes and a built-in loading state. | | ButtonGroup | Joined buttons and toggle segments in one neutral bar. | | LinkButton | A real link styled as a text action, sized on the control tiers. |
Inputs (inputs)
| Component | What it is for |
|---|---|
| Input | Single-line text field with label, hint, error and slots for icons, affixes, a clear button and a counter. |
| Textarea | Multi-line text field with label, hint, error and a character counter; grows with its content by default. |
| DigitInput | A row of square single-digit cells for a fixed-length code (OTP from SMS, PIN, pickup code), with the field label, hint and error. |
| FileUpload | One component for every set of files a person adds: a document field, file cards, an image gallery with a cover, an attachment tray — trigger picks how files are added, layout how they lie, cover makes the first tile the cover; uploads go through a queue, the order and removals can be saved on a server. |
| Label | Field label (native <label>) with required and optional markers. |
| Hint | Help text or a validation error under a field. |
| Fieldset | A frameless group of related form fields: a native <fieldset> with a title-s legend, the form rhythm between its fields and one disabled for all of them. |
| FieldList | An editable list of records of one shape — invoice lines, specs, contacts, prices by period: one row per record on one grid, the column headings once above the rows, the row's actions at its end and an add button under them. |
Selection (selection)
| Component | What it is for |
|---|---|
| Checkbox | A checkbox for an independent yes/no choice that submits with a form: checked, indeterminate, with a hint or an error. |
| Radio | Radio buttons for choosing exactly one option out of a small visible set. |
| Switch | An on/off switch for a setting that takes effect immediately. |
| SegmentedControl | A switch between 2–5 mutually exclusive options or modes that takes effect immediately. |
| Slider | A slider for picking an approximate numeric value within a range, with an optional label and value readout. |
| Select | A field for choosing one value (or several with multiple) from a closed list. |
| NativeSelect | The system <select> in the kit's field look: the operating system's picker opens on phones. |
| TagSelect | A multi-value field that shows the picked values as coloured tags, filters as you type and can create new tags. |
| SmartFilter | The search and filter bar of lists and tables: the search first and a filter button with a panel of values and ranges, applied filters as removable tags, and a "show / hide" choice for every value. |
| Datepicker | A calendar for picking a date or a date range: a field with a popover (Datepicker.Root) or an embedded panel (Datepicker.Panel). |
| ColorField | A form field for any color: the swatch and its hex in a field box that opens the ColorPicker in a popover. |
| ColorPicker | Color selection: a full picker (hex field, area, channel sliders and fields, eyedropper, swatches) and ColorPresets for a quick color from a fixed palette. |
| ColorSwatches | An inline color choice: preset swatches that fill the width of a form or panel and wrap, without a popover. |
Data display (data-display)
| Component | What it is for |
|---|---|
| Badge | The kit's one chip: a static label for a status, category or count, a removable value or applied filter, and a pressable toggle with a hover action — in a palette color. |
| Avatar | A round photo of a person or organization with an initials or icon fallback, a presence dot and overlapping groups. |
| Thumbnail | A preview of an object — product, vehicle, file, cover, video — at a fixed aspect ratio, with a colored icon fallback; it can open the object or be selected. |
| Carousel | Photos and videos of one record in one box of a fixed ratio: a finger or a mouse drag swipes them, the dots, the arrows and the keys step. |
| Kbd | A key cap for a keyboard key or a shortcut, rendered as a native <kbd>. |
| Card | A filled surface that holds one entity — a record, a plan, a setting, a listing — as a cover, a header with its mark, title, badges and actions, a body and a footer, parted by air and never by lines. |
| StatusDot | A state in a line of text: a dot of a tone and the word that names it. |
| Kpi | A KPI card: one figure and what it means — the head says what it is, the value and the line under it say how much and for when; the size decides which parts the card holds. |
| DataTable | A data table with sorting, pages or infinite scroll, row selection, row groups, rows that open a record, a column chooser, nested rows and loading / empty / error states. |
| Kanban | A board of status columns: cards reorder within a column and move between columns by pointer, touch hold and keyboard, with announcements, WIP limits, loading and empty states and a layout that scrolls inside itself at any width. |
| Gantt | A resource or project schedule: rows of people, rooms, vehicles or tasks with bars on a day / week / month axis, edited by pointer and keyboard. |
| Timeline | An event feed: dots on a thin line, event title and date, an optional amount on the right, grouped under labels. |
| CodeBlock | A static TypeScript / TSX snippet with syntax highlighting, on a filled panel or bare inside a host. |
| RichText | Text in the chat's Markdown subset — or a messenger's plain text with its entities — outside a message (a bot's welcome text, a template, a comment), rendered as elements, never as HTML. |
| Accordion | Collapsible sections: FAQ, settings groups, checkout steps. |
| Sparkline | A small chart with no headline of its own — a smooth line over a fading area, a bare, dashed or dotted line, or bars, with comparison lines beside it; useSparkline gives the value, change and date a card lays out, and they follow the scrubbed point. |
| ChartFrame | A dashboard panel around any chart — Recharts, ECharts, visx, Chart.js or a hand-drawn SVG — with the title, a headline value, a measured plot area, a series legend, a tooltip body and a data table for screen readers. |
| DescriptionList | Read-only properties of a record: «label — value» pairs on a <dl> that stack by themselves where the room is narrow, with a muted dash for an empty value. |
Messages (messages)
| Component | What it is for | |---|---| | Chat | A conversation, assembled: the header with who it is with, search, pinned messages, the virtualized message list with dates, runs, selection and jumps, typing, and the Composer at the bottom. | | Message | One chat message in its shell: a speech bubble, a picture or a circle, incoming or outgoing, the tail that ends a run, the time and delivery ticks in the corner, reactions, the menu, a group chat's author header, and every content kind of a messenger. | | VoicePlayer | A voice message player: a round play disk, a waveform that is the seek slider, and the time with the playback speed — the same player API as VideoNote. | | VideoNote | A round video message: a still first frame with the play disk that plays with sound on a press — the same player API as VoicePlayer. | | Composer | The message input of a chat: a field that grows from one line, Enter to send, attachments, a reply / edit bar, Markdown formatting of a selection, and voice or round video messages from the same button. | | Gallery | Photos and videos as a messenger album: one, or up to ten laid out from their aspect ratios alone, every box final before a byte loads; a tile opens the album in MediaViewer. | | ChatList | The conversation list of a messenger: the pane where the reader picks a dialog — avatar, name, time, the last message, counts, «печатает…» and drafts. |
Status and loading (status)
| Component | What it is for |
|---|---|
| Banner | Full-width in-flow message for a page, section or card: status icon, title, description, actions and dismiss. |
| Notification | Pop-up toast notifications: NotificationProvider at the app root and notify() from any screen. |
| ProgressBar | Linear progress: one value on a native <progress>, segments that split a whole (storage by type, leads by source) with an optional legend, or a ranking of rows (top cities, a funnel). |
| ProgressCircle | Circular progress — the ring version of ProgressBar: one value or segments that split a whole, with status colors and optional content in the center. |
| Spinner | An indeterminate loading indicator: the kit ring with the share unknown — a quarter arc turning on a faint track while a request runs. |
| Skeleton | A placeholder in the shape of the content that is loading — text lines, a control, an avatar, a block — so the layout is in place before the data arrives. |
| EmptyPage | Empty or failed state of a page, a block or a menu: icon, title, explanation and an action — a retry for a failed load. |
| Crossfade | A region that cross-fades between its states (loading → data → empty → error), opacity only: it takes the new state's height at once and the data replaces the loading skeleton in place — nothing unfolds or glides. |
| VisuallyHidden | Text that screen readers read and nobody sees: the words behind an icon, a badge or a change on the screen. |
Navigation (navigation)
| Component | What it is for | |---|---| | Tabs | A tab bar of folder tabs for navigating between content panels of one screen: the active tab is the host's surface rising into the strip, the panel is the host's content with no frame or padding of its own. | | Breadcrumb | Breadcrumbs: the path to the current page. | | Pagination | Page-by-page navigation: arrows, page numbers with ellipsis and a compact «3 / 12» view. | | Stepper | Steps of a multi-step process with pending, current, completed and danger statuses. | | Sidebar | App side navigation in three modes — expanded, compact, hidden — and an off-canvas panel on narrow screens. | | BottomNav | Phone navigation: a bar of 2–6 main sections at the bottom of the screen, optionally with a round action beside it. | | List | A list of records or places built of the kit's one list row — the row Sidebar, menus, Select, CommandMenu, Timeline and the file queue stand on: a mark, a title with its number and badges, a description, meta and controls. |
Overlays (overlays)
| Component | What it is for | |---|---| | Tooltip | A short hint that appears next to an element on hover or keyboard focus. | | Popover | A non-modal floating panel anchored to a trigger: short forms, filters, confirmations, explanations. | | Dropdown | A menu of actions that opens from a trigger: picking an item runs it and closes the menu. | | Modal | A dialog over the page for a short form or important text that must be finished or acknowledged before the page goes on. | | ConfirmDialog | The confirm of a destructive or weighty action in one piece: the question, the consequence, Cancel and an action that runs its own request. | | Drawer | A modal panel that slides in from the side: filters, forms and record details without leaving the page. | | Command Menu | A search palette over the page: the query filters commands and pages, Enter runs the active one. | | Sheet | A panel raised from the bottom edge for a short task that ends by itself: pick a date, choose an action, leave a few words. | | MediaViewer | A full-screen viewer of photos and videos that behaves like a native one: pages follow the finger, pictures zoom and pan with momentum, a swipe closes it, and it opens out of the thumbnail it came from. |
Page (page)
| Component | What it is for | |---|---| | AppShell | The app frame — navigation and the page: a content panel that is the page itself and a navigation rail one layer above it. | | Page | The page inside the app frame: everything at the top belongs to it — a top bar with the title, tools and buttons, the large document title in the flow — then sections, the tile grid and the list + detail layout. | | Divider | A hairline separator inside one surface, horizontal or vertical, with or without a label. | | ScrollContainer | The kit's one scroll region: a thin scrollbar, soft edges wherever content is hidden, and correct shrinking inside flex and grid parents. | | LoginForm | A sign-in card with a logo, title, provider buttons and a form; covers sign-in, sign-up, password reset and code confirmation. |
Interaction (interaction)
| Component | What it is for | |---|---| | Dnd | Pointer-driven drag and drop: reorderable lists, draggable items and drop zones on one shared session, with a lifted clone, a gap where the item lands, auto-scroll, touch support and a keyboard path. |
Infrastructure (infrastructure)
| Component | What it is for | |---|---| | ExampleFrame | A documentation frame: live preview, source code and device width in one block. |
Providers and helpers
| API | Purpose |
|---|---|
| NotificationProvider + useNotifications() | Toast queue: notify, dismiss, dismissAll. Place the provider once at the app root. |
| useAppShellNav() | The app shell's navigation for a trigger outside the Sidebar rail (a BottomNav «Ещё», your own menu button). |
| ControlSizeProvider | Default size for every control in a subtree (dense toolbars, compact forms). |
| Tooltip.Provider | Shared open delay for a group of tooltips. |
| applyTheme(scheme, element?) | Switch the theme without transition flashes. |
| celebrate({ origin? }) | A short confetti burst for a rare milestone (a quarter closed, the first payment); draws nothing under reduced motion. |
| getPasswordStrength(value) | The kit's 0–4 password estimate behind Input.Root strength; replace it with getStrength. |
| useUploadQueue({ upload, concurrency }) | The upload queue behind FileUpload queue: your upload(file, { signal, onProgress }) runs a few at a time, with progress, abort on remove and retry. |
| groupMessages, formatMessageDate, formatMessageTime, hueOf | Chat data → dated runs of one author (Chat.Messages items runs it for you), the date and time labels, and a palette hue stable per person. |
| formatChatTime(date, now) | The time of a dialog's last message as ChatList shows it: «14:32» today, «пн» this week, «12 мар», «12.03.2025». |
| getWaveform | The 0…1 levels of a recorded voice message (a Blob or a URL) for VoicePlayer waveform, decoded with the Web Audio API. |
| moveBefore(items, id, beforeId, getId) | Applies a Dnd or DataTable onReorder to your array. |
| matchesSmartFilter, resolveSmartFilterValues | Apply a SmartFilter value to your rows. |
| datepickerPresets, formatDatepickerValue | Quick ranges and value display for Datepicker. |
| formatDateValue(date, { withTime }) | A date as the local yyyy-MM-dd (THH:mm) value for a form or a query. |
| chartColors | The chart palette as CSS values for a chart library; follows the theme. |
| useTokenValue(token) | A length token in px for geometry CSS cannot take (SVG, canvas). |
| useMediaQuery(query, enabled?) | Whether a media query matches, live. Pass one of the kit's queries — COMPACT_QUERY (below 640px: Drawer full width, overlays as sheets), OFF_CANVAS_QUERY, TOUCH_QUERY, HOVER_QUERY, REDUCED_MOTION_QUERY — to switch a screen at the kit's own point. |
| <Icon name="…" />, createIcon(glyph) | The kit icon set: Lucide drawings, each with a small gesture that plays when its host is hovered or pressed; createIcon turns any SVG icon component (a lucide-react glyph you install, an SVGR import) into a kit icon. |
Docs inside the package
Each component folder ships with the package:
node_modules/prime-ui-kit/src/components/<name>/COMPONENT.md full reference
node_modules/prime-ui-kit/src/components/<name>/examples/*.tsx one scenario per file, copyable
node_modules/prime-ui-kit/src/layout/<name>/… AppShell, Sidebar, BottomNav, Page
node_modules/prime-ui-kit/dist/skill/SKILL.md the agent skill (see below)Examples import only from "prime-ui-kit" and style layout with a local examples.module.css on
--prime-* tokens, so a file works as-is in your project. The same files power the playground.
Agent skill
SKILL/ teaches an AI coding agent to build UI
with the kit the way its author would: the screen-building process, the design rules in "do this" form,
the API cheat sheet, how to choose between similar components, what to do when a component is missing,
page recipes (dashboard, list with table, settings, forms, detail page, screen states, messenger, auth), anti-patterns
and a review checklist. The package ships it built as one self-contained folder,
node_modules/prime-ui-kit/dist/skill/: SKILL.md, the guides, and under reference/ every
component's COMPONENT.md and examples/ (whole screens included, as examples/screen.tsx) and the
design contract, so it always matches the installed version.
Install the skill
After npm install prime-ui-kit, from the project root:
npx prime-ui-kit skill # Claude Code, this project: .claude/skills/prime-ui-kit
npx prime-ui-kit skill ~/.claude/skills/prime-ui-kit # Claude Code, all your projectsCommit .claude/skills/prime-ui-kit so the whole team gets it. The command only copies the folder
(Node built-ins, no network); a plain copy does the same:
rm -rf .claude/skills/prime-ui-kit && mkdir -p .claude/skills
cp -R node_modules/prime-ui-kit/dist/skill .claude/skills/prime-ui-kitOther agents (Cursor, Codex, …): pass the agent's skills or rules directory
(npx prime-ui-kit skill .cursor/skills/prime-ui-kit), or point the agent at SKILL.md in the
package.
The agent picks the skill up automatically when you ask it to build or review a screen ("build a settings page with prime-ui-kit", "check this screen against the design system"). After upgrading the kit, run the command again: it replaces the folder with the skill of the new version.
Package exports
| Path | Purpose |
|---|---|
| prime-ui-kit | The JS/TS API: every component, layout, icon, hook and helper. It brings the base CSS (tokens, both themes, focus ring, reduced motion); every component brings its own; only what you import is bundled. |
| prime-ui-kit/color-picker | ColorPicker, ColorField and parseColor — the only code on the optional peer react-aria-components. |
| prime-ui-kit/icons | The full animated glyph set as named components (<BellIcon />): Lucide drawings, one gesture each; only what you import is bundled. |
| prime-ui-kit/fonts.css | Optional: Golos Text and JetBrains Mono from Google Fonts, with metric-matched local fallbacks, so text does not move when a face arrives. Offline or under a strict CSP self-host the faces instead (@fontsource/*). |
| prime-ui-kit/reset.css | Optional: minimal document reset. |
| prime-ui-kit/tokens.css, theme-light.css, theme-dark.css | The token layers alone (already brought by prime-ui-kit), for styling without components. |
Type definitions ship with the package.
Development
bun install
bun run playground:dev # docs site with every component and scenario
bun run verify # biome, typecheck, tests (incl. docs contract), build (with the skill)Contributor rules: AGENTS.md. A change to a component updates
its code, tests, examples, playground section and COMPONENT.md together; the docs-contract test
keeps them in sync.
FAQ
What is prime-ui-kit? A React 19 component library for product interfaces (admin panels, dashboards, settings, forms, data tables) with its own design system "Graphite", built on CSS Modules and CSS custom properties.
Which React version does it need? React 19 (react and react-dom ^19) and the peer
dependency date-fns ^4. react-aria-components ^1.16 is an optional peer, needed only for
prime-ui-kit/color-picker (ColorPicker, ColorField).
Does it use Tailwind? No. Styles are CSS Modules shipped beside each component and imported by it; theming is
done with --prime-* CSS variables and data-theme="light" | "dark".
How do I switch to the dark theme? Call applyTheme("dark") or set data-theme="dark" on <html>
or any wrapper.
Where is the documentation for a component? In the package: node_modules/prime-ui-kit/src/components/<name>/COMPONENT.md
and …/examples/*.tsx; on GitHub: the links in the Components table.
What language are the built-in strings in? Russian. Every system string (aria labels, counters,
default texts) can be replaced through the component's labels prop.
Can an AI agent build screens with it? Yes — run npx prime-ui-kit skill to install the
agent skill shipped in the package; it teaches the agent the design rules, the
API and page recipes and points it to each component's docs.
Does it work with Next.js App Router? Yes — the package is marked "use client"; build screens
in client components and render them from server pages (details).
License
MIT — see LICENSE. Icon drawings come from
Lucide (ISC); their gestures are adapted from
lucide-animated (MIT) — notices in
THIRD_PARTY_NOTICES.
