Skip to content
v1.0 · 36 componentsCommand and Data table are new

Components you own, themes you control.

Plinth is a themeable component library for React and Tailwind CSS. Thirty-six accessible components you copy into your project, driven by one accent, one radius and two themes.

Browse components Open themes
Try an accent
Graphite
components
36
accents
6
radius presets
5
runtime dependencies
0

Why Plinth

A calm foundation for serious product UI.

Accessible from the first line

Native buttons, inputs and dialogs first. Roles, labels and keyboard support follow the WAI-ARIA patterns, and focus is always visible.

Save changesTab Enterrole="switch" aria-checked="true"

Themeable with three switches

One accent, one radius and a light and dark palette drive every component. Change a variable and the whole interface follows.

data-accentdata-radius.dark

Yours to own

No package to install and no API to wait on. Each component is one readable file in your repo. Rename it, extend it, delete it.

components/ui/button.tsxdialog.tsxdata-table.tsx

The catalogue

36 components, one consistent voice.

Inputs, overlays, navigation and data display. Each with live examples, a props reference and accessibility notes.

Themes in one click

Six accents. Five radius options. Light and dark.

Pick a preset and the whole site follows, this page included. Every component is tested with every combination.

  • Saved per visitor, applied before first paint
  • Accent text stays readable, even in graphite
  • Copy the CSS variables for your project
Open the theme customizer

Accent

Radius

Graphite · Medium

Examples

Full screens, built only from Plinth.

Four example apps show the components working together. Open one, switch the accent, then take what you need.

Source included

Copy the file. Change anything.

Every component is a single TypeScript file built on Tailwind tokens. Read it in a minute, then make it yours: add a variant, change a class, wire it to your data.

  • Typed props, no wrappers
  • Semantic tokens, never hex codes
  • Keyboard support written in
components/ui/badge.tsx
import { cn } from "./cn"; const tones = {  neutral: "bg-raised text-muted border-line",  accent: "bg-accent-soft text-accent border-accent/25",  success: "bg-success/10 text-success border-success/25",}; export function Badge({ tone = "neutral", children }: BadgeProps) {  return (    <span className={cn("inline-flex h-5 rounded-full border px-2", tones[tone])}>      {children}    </span>  );}

Start with one component.

Copy a button today, the whole library tomorrow. Plinth grows with your product and never gets in its way.

Suggested