A theme generator produces eleven pairs of CSS variables. They all produce valid output; what separates them is whether the output survives contact with a real application, and the failures are consistent enough to be a checklist.
What a generator has to get right
Both modes, designed rather than derived. Almost every tool lets you tune one and generates the other. The generated half is where the failures live: borders that vanish, muted text that fails contrast, a ring that disappears against its own background.
Contrast on the pairs that carry text. --muted-foreground on --background is used for every timestamp, caption and table header, and it is the pair that most often falls under 4.5:1. A generator that shows you the ratio is doing the useful part.
The ring. --ring is the focus indicator for every interactive element at once. A generator that treats it as an aesthetic choice rather than as an accessibility requirement will hand you an invisible one.
The chart and sidebar tokens. Nobody previews these, and a theme whose five chart colours are indistinguishable in greyscale produces an unreadable dashboard.
The Tailwind version. v4 moved configuration into CSS, so output written for v3's JavaScript config needs translating rather than pasting, which is the commonest reason a copied theme appears to do nothing.
The three kinds of tool
Visual editors. You move sliders and watch real components change. This is the right shape, because a palette is judged on components rather than on swatches, and it is the only kind that makes the dark half visible while you work.
Palette generators. You give a brand colour and get a scale. Useful for the accent ramp, and they typically stop before the token set, leaving you to map a scale onto --muted, --accent and the rest, which is the part that requires judgement.
Collections. Ready-made themes to take whole. Fastest by a distance, and the 623 community themes are the version of that with both modes and a live preview. The themes guide has the four checks to run before shipping one.
The generator most people actually need
Start from a theme that is close and rotate the hue. Choosing eleven colours from scratch is a design exercise; adapting a set that already has its contrast relationships worked out is an afternoon.
If you are building from nothing, work in OKLCH, where holding lightness and chroma while rotating hue produces a family that feels related. The theming guide covers why that space behaves differently from HSL, and the one rule that saves a rebuild: derive the neutrals from the accent, because a grey with a slight hue bias reads as chosen and a pure grey reads as default.
Checking the output before you ship it
Five minutes, and it catches everything above.
Put a form, a table, a chart and a dialog on one screen. Switch to dark. Look at four things: the borders on cards, the muted text under headings, the focus ring on a button after pressing Tab, and the chart series in greyscale. If all four hold, the theme is fine; if any fails, it fails everywhere, because that is what a token is.
Where else to look
The honest list, because the answer is not always us:
| Source | Best for | Trade-off |
|---|---|---|
| tweakcn | Editing tokens visually against real components | A tool, not a collection |
| shadcn/ui themes | The official base palettes, guaranteed to fit | Deliberately neutral, and a small set |
| oklch.com | Building a palette in a uniform space, gamut warnings included | You choose every value |
| Community themes | 623 free themes with both modes and a preview | Community-made, so run the checks yourself |
Taking one
A theme is CSS variables, so applying one is replacing a block in your global stylesheet: the :root set for light and the .dark set for dark. Nothing to install. The 21st MCP does the same from the editor: ask Claude, Cursor or Codex for a theme, get the palettes inline, and let the agent write the block.
Frequently asked
- What separates a good shadcn theme generator from a bad one?
- Four things: whether the dark set is designed rather than derived, whether it shows contrast ratios for the pairs that carry text, whether it treats the focus ring as an accessibility requirement rather than a colour choice, and whether it produces the chart and sidebar tokens nobody previews.
- Should I generate a theme or start from an existing one?
- Start from one that is close and rotate the hue. Choosing eleven colours from scratch is a design exercise; adapting a set whose contrast relationships already work is an afternoon. Building from nothing is worth it only when the brand palette genuinely demands it, and then work in OKLCH.
- How do you check a theme before shipping it?
- Put a form, a table, a chart and a dialog on one screen and switch to dark. Check card borders, muted text under headings, the focus ring after pressing Tab, and the chart series in greyscale. If any of those fails it fails everywhere, because that is what a token is.
- Why does a generated theme not work in my project?
- Usually a Tailwind version mismatch: output written for v3's JavaScript config has to be translated into a v4 @theme block rather than pasted. The other cause is a deeper override already in your cascade winning over the variables you just set.