Getting started
ploxum ships as six @roger-emerson/ploxum-* packages plus a registry of copy-in composites. The packages are not yet on npm — until they are (see Roadmap), consume them by vendoring from a local checkout. The setup below is identical once you have the packages resolvable; only the install line changes when npm publication lands.
Install
Once published, this is the whole install:
# (after npm publication)
pnpm add @roger-emerson/ploxum-primitives @roger-emerson/ploxum-tokens @roger-emerson/ploxum-icons @roger-emerson/ploxum-utilsUntil then — vendor from a local checkout. Build the packages once, then either pack them to tarballs or link them:
# in the ploxum-ui checkout
pnpm --filter "./packages/*" build
# Option A — tarballs (self-contained, no path coupling):
cd packages/primitives && pnpm pack # → roger-emerson-ploxum-primitives-<version>.tgz
# …repeat for tokens, icons, utils (and motion/intl if used), then in your app
# (use the actual packed versions — currently primitives 0.5.0, motion/tokens 0.2.0, icons 0.2.1, utils 0.1.0):
pnpm add ./roger-emerson-ploxum-primitives-0.5.0.tgz ./roger-emerson-ploxum-tokens-0.2.0.tgz \
./roger-emerson-ploxum-icons-0.2.1.tgz ./roger-emerson-ploxum-utils-0.1.0.tgz
# Option B — local link (tracks the checkout, good while iterating):
pnpm add "@roger-emerson/ploxum-primitives@link:../ploxum-ui/packages/primitives" # …and the restPeer deps your app supplies: react@^19, react-dom@^19, motion@^12, tailwindcss@^4 + @tailwindcss/vite, and the three variable fonts:
pnpm add @fontsource-variable/inter @fontsource-variable/plus-jakarta-sans @fontsource-variable/jetbrains-monoSet up styles (Tailwind v4)
This is the load-bearing step. ploxum components read design-token CSS variables and Tailwind utilities derived from them (text-tertiary, border-subtle, bg-card, text-foreground, …). Both come from the token package. Your global stylesheet needs every line below:
/* app/globals.css */
@import "tailwindcss";
/* Fonts (Inter body, Plus Jakarta Sans display, JetBrains Mono numerals) */
@import "@fontsource-variable/inter";
@import "@fontsource-variable/plus-jakarta-sans";
@import "@fontsource-variable/jetbrains-mono";
/* Token variables + at least one theme. cinematic is dark-only; */
/* add amber-minimal only if you offer a theme switch. */
@import "@roger-emerson/ploxum-tokens/css";
@import "@roger-emerson/ploxum-tokens/themes/cinematic.css";
@import "@roger-emerson/ploxum-tokens/themes/amber-minimal.css";
/* The Tailwind v4 wiring: @theme inline map + dark variant + base helpers */
/* (.cinematic-only, .tnum, .scrim, .scrollbar-none, the border-color reset). */
@import "@roger-emerson/ploxum-tokens/theme.css";
/* Tailwind v4 does NOT scan node_modules by default. Point it at the */
/* installed component source so their class strings get generated. */
@source "../node_modules/@roger-emerson/ploxum-primitives/dist";Wire the Tailwind Vite plugin (Next.js: use the PostCSS plugin per Tailwind v4 docs):
// vite.config.ts
import tailwindcss from "@tailwindcss/vite";
import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";
export default defineConfig({ plugins: [react(), tailwindcss()] });Then import the stylesheet once at your entry (import "./globals.css").
Wrap your app
import { PloxumProvider, TooltipProvider, ToastProvider } from '@roger-emerson/ploxum-primitives';
export function App({ children }) {
return (
<PloxumProvider theme="cinematic" mode="system" density="comfortable">
<TooltipProvider>
<ToastProvider>{children}</ToastProvider>
</TooltipProvider>
</PloxumProvider>
);
}<PloxumProvider> owns three pieces of state, all optional with sensible defaults. It only sets attributes on <html> (data-theme, data-density, .dark) — the visual result depends on the CSS imports above being present.
| Prop | Default | Effect |
|---|---|---|
theme | "cinematic" | Sets data-theme on <html>. Choose between "cinematic" and "amber-minimal" out of the box (or your own — see Themes). |
mode | "system" | "light" | "dark" | "system". Coerced to the theme's only mode when single-mode (cinematic = always dark). Toggles .dark on <html>. |
density | "comfortable" | "compact" (NOC walls, 28px row height) or "comfortable" (laptops, 40px row). |
TooltipProvider is required by any tooltip-bearing component; ToastProvider only if you use Toasts. State persists in localStorage under ploxum.theme and ploxum.mode.
Add a theme switcher
Drop the picker primitives into your TopBar or settings panel:
import { ThemeSwitcher, ModeToggle } from '@roger-emerson/ploxum-primitives';
<header>
{/* …your nav, breadcrumbs, search… */}
<div className="flex items-center gap-2">
<ThemeSwitcher variant="compact" />
<ModeToggle />
</div>
</header><ModeToggle /> returns null automatically when the active theme has only one mode, so cinematic shows no toggle without any conditional logic on your side.
Read theme state
Any descendant can call useTheme():
import { useTheme } from '@roger-emerson/ploxum-primitives';
function MetricCard({ children }) {
const { resolvedMode } = useTheme();
return <div data-mode={resolvedMode}>{children}</div>;
}resolvedMode is always "light" or "dark" — "system" resolves dynamically via prefers-color-scheme.
Cinematic-only effects
Effects that only render correctly under the cinematic palette (e.g. a warm bokeh wash on a focal canvas) wrap in .cinematic-only — the hide-under-other-themes rule already ships in theme.css, so no extra CSS is needed:
<g className="cinematic-only">
<ellipse fill="url(#floor-glow)" /* …amber radial gradient… */ />
</g>The effect renders under cinematic and hides under every other theme automatically.
Add registry composites
Composites and templates (DataTable, AlertCenter, CommandShell, …) are copied into your repo, shadcn-style, rather than installed — you own and can edit the source. Point the CLI at the registry and add by name:
npx ploxum init # writes ploxum.config.json (componentsDir, registryUrl)
npx ploxum add data-table alert-centerEach item lands under your componentsDir and the CLI prints the npm deps to install (e.g. @tanstack/react-virtual for DataTable). Composites import the @roger-emerson/ploxum-* packages, so the install + style setup above must be in place first.
Next steps
- Themes — the two-layer token model and how to add a tweakcn theme.
- Tokens — DTCG source, generated outputs, shadcn alias layer.
- Components — the 45-component package + 16-item registry catalog with Storybook deep links.
- Principles — the 10 UX heuristics every component honors.
- See the demo — a live operational dashboard built entirely from ploxum.
