A zero-dependency, fully-styled React component library built for projects that want structure + accessibility + behaviour from the library and own visual identity in their own SCSS.
Install · Quick start · What's inside · Theming · For AI agents
Radix without the styling sweat. shadcn without the fork-forever tax. Radix daje a11y. shadcn daje style. Tylko my dajemy oba — i propagujemy fixy przez
npm update.
Three walls hit every product team:
| Approach | What you get | What hurts |
|---|---|---|
| Headless (Radix, Headless UI) | Accessible primitives | Every project re-invents the design system from scratch |
| Styled (MUI, Chakra, Ant Design) | Pre-built look | Locked into their design language + runtime dependency |
| Copy-paste (shadcn/ui) | Great starting point | Every project forks forever — fixes don't propagate |
@bleizlabs/ui sits between them: fully styled out of the box, zero runtime UI dependencies, seed-token driven. Override 5–10 seed values and the entire library reskins consistently — without forking source code.
npm install @bleizlabs/ui
npm install -D sassPublic on npm — no auth, no .npmrc setup.
sassis an optional peer dependency: the library ships raw SCSS Modules compiled by your build (Next.jssassOptionsbelow), so the consumer project needssassinstalled. It is marked optional so npm never force-installs it where SCSS is precompiled.
Migrating from an older internal release? If your
.npmrccontains@bleizlabs:registry=https://npm.pkg.github.com, remove that line — the package moved to public npm registry in0.22.x.
For a fresh Next.js 16 + React 19 project, run one command:
npx @bleizlabs/ui initThis generates:
- A wrapper layer at
app/_components/ui/— thin re-exports per family that you import from instead of@bleizlabs/uidirectly. Lets you add project-specific variants without forking the library. app/globals.scsswith seed-token override scaffoldingtsconfig.jsonpath aliases (@/components/ui,@/components/shared)AGENTS.md+CLAUDE.mdwith project discipline rules for AI coding agentsdocs/component-inventory.mdfor tracking project-local components
Re-runs are idempotent. After upgrading the lib: npx @bleizlabs/ui add --new to scaffold wrappers for new components.
If you're integrating into an existing project or skipping the wrapper layer, three steps:
1. Configure Next.js (next.config.mjs):
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
/** @type {import('next').NextConfig} */
export default {
transpilePackages: ['@bleizlabs/ui'],
sassOptions: {
loadPaths: [path.resolve(__dirname, 'node_modules/@bleizlabs/ui/styles')],
},
};2. Bootstrap styles (app/globals.scss):
@use '@bleizlabs/ui/styles';
// Optional: prettier global scrollbars
@use '@bleizlabs/ui/styles/scrollbar';3. Import + use:
// app/page.tsx
import { Card, CardHeader, CardBody, Heading, Text, Button, Stack } from '@bleizlabs/ui';
export default function Page() {
return (
<Card padding={6} radius="lg">
<CardHeader>
<Heading level={1} size="2xl">
Hello from @bleizlabs/ui
</Heading>
</CardHeader>
<CardBody>
<Stack gap={4}>
<Text variant="body" color="secondary">
Fully styled, zero deps, seed-token driven.
</Text>
<Button variant="primary">Get started</Button>
</Stack>
</CardBody>
</Card>
);
}That's it. No provider wrapping, no theme context, no runtime style computation.
100+ focused components across 9 categories (live count in components/manifest.json — read for the canonical list at any version).
| Category | Highlights |
|---|---|
| Layout | Stack · Inline · Container · Section · GridLayout |
| Typography | Heading (decoupled level/size) · Text · Anchor · Eyebrow · Mark |
| Display | Card (compound) · Badge · Avatar · KpiValue · Reveal · Skeleton · Spinner · Table · CodeBlock |
| Interactive | Button · Input · Checkbox · RadioGroup · Switch · Toggle · Rating · NumberInput · TagsInput · SkipLink |
| Feedback | Alert · Banner · Empty · Progress |
| Specialized + Navigation | Breadcrumb · Pagination · ThemeToggle · Kbd + small data-viz primitives |
| Molecules | Header · Chip · DataRow · FileChip · BackLink · IconButton · Timeline · AvatarGroup and more |
| Charts | LineChart · AreaChart · BarChart · PieChart · Sparkline (SVG, ≤500 points/series) |
| Complex / Data | Dialog · Sheet · Drawer · Popover · Tooltip · DropdownMenu · Select · Slider · Combobox · DataTable · Form + Field · Toaster (imperative toast() API) · DatePicker · DateRangePicker · TimePicker · DateTimePicker · Sidebar · Tabs · Accordion · Stepper · NavigationMenu · Toolbar |
Highlights:
- Zero runtime UI dependencies — every floating primitive, focus trap, drag gesture, date utility, and keyboard model is built in-house. No Floating UI, no date-fns, no Recharts, no Radix at runtime.
- APG-first accessibility — every interactive component maps to a documented WAI-ARIA Authoring Practices pattern with full keyboard model + ARIA contract.
- Runtime-test-verified — Playwright keyboard / focus / aria / regression suites per component +
@axe-core/playwrightWCAG 2.1 AA sweep across all playground routes. - 100% JSDoc coverage — every component carries
@layer/@tokens/@deps/@a11y/@exampletags. Readnode_modules/@bleizlabs/ui/components/<category>/<Name>/<Name>.tsxfor per-component API truth. - React 19 + Next.js 16 — Server Components by default,
'use client'only at interactive leaves, FloatingPortal hydration mount-gated, React Compiler compatible. - Form-native —
<Form>+<Field>compound reads FormData natively via the Constraint Validation API. NouseStateper field.
Two cascade layers cover most cases.
Override semantic tokens at :root. Cascades to every component automatically.
// app/globals.scss
:root {
--color-brand: #00e0b8;
--color-accent: #7c3aed;
--radius-md: 12px;
--font-primary: 'YourFont', system-ui, sans-serif;
}
[data-theme='dark'] {
--color-surface: #0a0a0a;
--color-text-primary: #fafafa;
}Full token reference: styles/_semantics.scss.
Override seed Sass variables when you want the entire color scale + derived shadows + hover states to follow a new brand colour consistently.
@use '@bleizlabs/ui/styles' with (
$seed-brand: #00e0b8,
$seed-accent: #7c3aed,
$seed-font-primary: (
'YourFont',
system-ui,
sans-serif,
)
);Every seed in styles/_project-settings.scss carries !default — pass only what you care about.
For one-off visual treatments, compose locally via className rather than fork the library:
import { Button } from '@bleizlabs/ui';
import styles from './GradientButton.module.scss';
<Button className={styles.gradient}>Launch</Button>;If the same styled pattern repeats across 2+ pages, extract a shared molecule wrapping the lib component — see docs/AGENT-USAGE.md §C for the full decision rules.
The library ships an agent-friendly cheat-sheet inside the npm tarball:
- Entry point (
AGENTS.md, ~80 LOC) — mission paragraph, Q1-Q5 reuse-first decision tree, anti-patterns table, pointers to deeper docs - Deep reference (
docs/AGENT-USAGE.md, ~750 LOC) — installation walkthrough, three-layer token cascade, SSR / RSC / Next.js 16 mapping, 9 per-domain quick-starts, troubleshooting table, full component inventory auto-generated frommanifest.json
After npm install @bleizlabs/ui, both files live under node_modules/@bleizlabs/ui/. Agents like Claude Code, Codex, and Cursor do NOT auto-scan node_modules/ — you point them explicitly. Add this snippet to your project's own AGENTS.md:
When working with @bleizlabs/ui, explicitly Read `node_modules/@bleizlabs/ui/AGENTS.md`
at the start of any UI task. Drill into `node_modules/@bleizlabs/ui/docs/AGENT-USAGE.md`
for per-domain detail. Both files ship inside the npm tarball.If you ran npx @bleizlabs/ui init, the generated consumer-side AGENTS.md already includes a Lib Reference section pointing at these paths.
Each doc carries a **Valid for:** @bleizlabs/ui <version> header injected at publish time — agents can compare against npm view @bleizlabs/ui version to detect cached-stale state after lib upgrades.
Every component has a dedicated demo route. To run locally:
git clone https://github.com/BleizLabs/ui.git
cd bleizlabs-ui/dev
npm install
npm run devOpen http://localhost:3000 for the component index, /demo for a combined showcase, or /components/<name> for per-component deep dives. Every component is dual-theme from day one.
- SCSS Modules only — scoped class names, zero runtime style computation, no CSS-in-JS, no Tailwind
- Zero runtime UI dependencies — positioning, focus trap, dismiss, drag, match-media, date math all in-house
- Semantic tokens — components reference
var(--color-brand), never primitive scale values - Compound flat API —
<Card>+<CardHeader>+<CardBody>as siblings (shadcn-aligned, IDE-friendly, tree-shakeable) - Polymorphism via
asChild— pass-through rendering for<Link>, custom elements, etc., powered by an in-houseSlotprimitive - APG-first accessibility — every interactive component has a documented keyboard model, ARIA contract, and regression test catalogue
| Layer | Choice |
|---|---|
| Framework | React 19 + Next.js 16.2 (App Router, Turbopack) |
| Language | TypeScript 5.6 (strict, noUncheckedIndexedAccess) |
| Styling | SCSS Modules + CSS custom properties (seed → semantic cascade) |
| Polymorphism | In-house Slot primitive (Radix-style asChild) |
| Positioning | In-house useFloating + computePosition |
| Date math | In-house utils/date.ts (native Date + Intl) |
| Focus management | In-house useFocusTrap + findFirstTabbable |
| Drag gestures | In-house usePointerDrag with pointer-capture |
| Testing | Playwright + @axe-core/playwright |
No external UI library is imported at runtime.
Every release passes:
- Smoke sweep —
@axe-core/playwrightWCAG 2.1 AA scan across every playground route, run against a production build - Per-component suites — keyboard / focus / ARIA state / regression tests for every interactive primitive
- NVDA sweep protocols — manual screen-reader checklists for NVDA + Firefox per interactive component
npm run test # full Playwright suite
npm run test:smoke # axe-core sweep only
npm run typecheck # tsc --noEmit
npm run lint # ESLint| Browser | Minimum version |
|---|---|
| Chrome / Edge (Chromium) | 111+ (Accordion interpolate-size: allow-keywords requires 129+; falls back to max-height) |
| Firefox | 110+ |
| Safari (desktop + iOS) | 16.4+ |
Every component ships with prefers-reduced-motion: reduce fallbacks and forced-colors: active (Windows High Contrast) mappings where relevant.
Pre-1.0. Minor bumps (0.X.0) may include breaking changes — read CHANGELOG.md before upgrading. Patch bumps (0.X.Y) are safe.
The library will hit 1.0.0 on an explicit stabilization trigger from maintainers, not auto-follow from minor count.
- 📦 npm package
- 📓 CHANGELOG
- 🗺️ ROADMAP
- 🤖 Agent docs (
AGENTS.md) · Deep reference (docs/AGENT-USAGE.md) - 🐛 Issues
- 🔒 Security policy
This library is open-source for visibility but not currently accepting external contributions. See CONTRIBUTING.md for details.
MIT — see LICENSE. © BleizLabs.