Skip to content
Start

Get started

Two lines and you are running. Klyv ships prebuilt CSS, so there is no Tailwind to configure, no plugin to register and no theme file to copy before the first component renders.

package to install
One
runtime dependencies
2
of CSS, gzipped
14.7 kB
or 19, as a peer
React 18.3+

Step 1: Install

One package. React is a peer dependency, so bring your own.

bash
npm install klyvui# pnpm add klyvui   ·   yarn add klyvui   ·   bun add klyvui

react and react-dom are peer dependencies — React 18.3 or 19, installed by you. The only runtime dependencies klyvui adds are clsx and tailwind-merge.

Step 2: Import the stylesheet

Pick one of two, depending on whether the project already runs Tailwind.

No Tailwind

Most projects
tsx
import 'klyvui/styles.css'

Prebuilt and complete: the tokens, the base layer, the keyframes and exactly the utilities the library uses. About 14.7 kB gzipped. You do not need Tailwind installed.

Already using Tailwind

css
@import 'tailwindcss';@import 'klyvui/preset.css';

Import the preset instead, in your own CSS entry. The utilities are generated into your build rather than shipped a second time alongside it.

Export

What it is

klyvui

The components, cn, the token registry and the theme API.

klyvui/styles.css

The prebuilt stylesheet. No Tailwind required.

klyvui/preset.css

Tokens plus an @source, for projects already running Tailwind.

klyvui/tokens.css

The tokens on their own.

klyvui/tokens.json

The tokens as W3C Design Tokens data.

Step 3: Render something

That is the whole setup. This is a real one.

Button

Takes its colour from the accent

+10%

Badge

Same accent, quieter role

tsx
import { Badge, Button } from 'klyvui'import 'klyvui/styles.css'​export default function App() {  return (    <>      <Button>Send</Button>      <Badge>+10%</Badge>    </>  )}

Step 4: Pick your accent

Four CSS custom properties are derived from one colour and written to the document. Nothing in the library hard-codes a colour, so one call repaints all of it.

ts
import { applyAccent, saveAccent, restoreAccent } from 'klyvui'​// Once, as the app boots: re-apply whatever the visitor last chose.restoreAccent()​// Whenever they pick a new one.applyAccent('#8b5cf6')saveAccent('#8b5cf6')

The text colour that sits on the accent is chosen by contrast, not by a lightness threshold, so any hue you pass stays readable. Use text-accent-ink for your own labels on an accent fill rather than picking black or white yourself.

The accent is one of five theme choices: base colour, radius, font and style work the same way, through applyTheme. Try the theme customiser to pick all five and copy the result.

Step 5: Dark mode

Token values change; token names never do. No component has a dark variant, and there is not a single dark: class in the library.

ts
import { applyMode, restoreMode } from 'klyvui'​restoreMode()        // on boot — light, dark or system, as last savedapplyMode('dark')    // switch nowapplyMode('system')  // follow the operating system, and keep following it

system follows the operating system and keeps following it, so a visitor who changes theme at lunch does not have to reload. Call restoreMode() once as the app boots to re-apply whatever they last chose.

Step 6: Or copy the source instead

If you would rather own the file than depend on the package.

bash
npx klyvui add data-table   # the component and everything it importsnpx klyvui list drag        # search by name, group, section or descriptionnpx klyvui info combobox    # what it would bring with itnpx klyvui add block login  # a whole screen, into src/blocks

The folders are flat and every internal import is relative, so copied files compile where they land — no rewriting and no codemod. Dependencies come with it: two thirds of the library imports at least one sibling, so a single file on its own would not build.

Good to know

The things that usually come up next.

ESM only

One module per component with sideEffects declared, so a bundler drops everything you do not import.

Types are included

Written in TypeScript and shipped with declarations. Every prop table on this site is generated from those same types.

Bring your own icons

An icon is a structural type, not an import: anything taking size, strokeWidth and className works — Lucide, Phosphor, your own SVG.

Server components work

Modules that can run on a server boundary do, and the rest already carry 'use client'. There is nothing to configure.

Where to next