Skip to main content
skill CX Codex

21st-design-sync — Claude Code skill: what it does, how to install

Extracts shadcn and Tailwind CSS tokens from your project and publishes them as a public theme on 21st.dev using the 21st CLI.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add 21st-dev/skill --skill 21st-design-sync -a claude-code
Open on GitHub

What 21st-design-sync does

This skill scans files like globals.css or index.css for design tokens. It extracts :root and .dark blocks containing standard shadcn variables such as --background, --primary, and --radius. If the project lacks a dark theme, it builds a matching .dark block by inverting lightness while keeping hue and chroma.

Publishing uses @21st-dev/cli via 21st publish-theme. Standard login tokens fail here: the management endpoint requires a dedicated 21st_sk_… key passed through --api-key or the TWENTYFIRST_TOKEN variable.

Published themes are immediately public in the community catalog. There is no private mode. Because each command execution registers a separate entry instead of updating an existing record, modifying metadata requires 21st edit.

What it helps with

  • publish shadcn and Tailwind tokens to the 21st.dev library
  • extract CSS variables into a standalone theme file
  • generate an on-brand dark palette when only light tokens exist
  • share a project color scheme via a public URL

Example prompts for the agent

  • Publish my project theme to 21st.dev
  • Turn my globals.css into a 21st theme named Acme
  • Sync my design tokens to 21st with minimal and dark tags

How to install 21st-design-sync

1Skills CLI (Vercel)

npx skills add 21st-dev/skill --skill 21st-design-sync -a claude-code

2Manually: put the files in place

~/.claude/skills/21st-design-sync/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/21st-design-sync/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about 21st-design-sync

How to install 21st-design-sync in Claude Code?

Run npx skills add 21st-dev/skill --skill 21st-design-sync -a claude-code. You can also place the skill file directly at ~/.claude/skills/21st-design-sync/SKILL.md.

Which API key is required to publish?

You need a key starting with 21st_sk_… from https://21st.dev/mcp or https://21st.dev/settings/api-keys. CLI session tokens from 21st login are not supported.

Can themes be published privately on 21st.dev?

No, all published themes are immediately public. If design tokens must remain private, do not publish them.

Source text

SKILL.md · Apache-2.0
---
name: 21st-design-sync
description: >-
  Look at the current project's design (its shadcn / Tailwind CSS variables and
  color tokens) and publish it to the 21st.dev community as a shareable theme,
  using `21st publish-theme`. Use when the user says "publish my theme",
  "share our design as a 21st theme", "sync my design to 21st", "turn my
  globals.css into a theme", "залей наш дизайн темой", "опубликуй тему". This is
  the 21st equivalent of design-sync: it reads the project's design tokens and
  syncs them into the public theme library.
---

# 21st Design Sync — publish your project's design as a theme

Take the design a project already ships (its light + dark CSS variables) and
publish it to the **public** 21st.dev theme library so anyone can preview,
bookmark, and apply it. Under the hood this is one CLI call:
`21st publish-theme <file.css> --name "…"`.

## Pre-flight (always)

1. **Auth needs a real API key.** `publish-theme` is a management endpoint: it
   accepts a `21st_sk_…` key **only**, not a `21st login` session token. Get one
   at **https://21st.dev/mcp** (or **https://21st.dev/settings/api-keys**) and pass it via
   `--api-key 21st_sk_…` or the `TWENTYFIRST_TOKEN` / `API_KEY_21ST` env var. If
   the user has no key, point them there — don't try to mint one.
2. The CLI is the unified `@21st-dev/cli` (bin `21st`). Use `npx @21st-dev/cli`
   if it isn't installed.
3. **Publishing is public and outward-facing.** A published theme is immediately
   `is_public` in the community library (there is no unlisted/private option for
   themes). Confirm with the user before publishing.

---

## Step 1 — Find the project's design tokens

Locate the file that defines the shadcn/Tailwind theme variables. Check, in order:

- `app/globals.css`, `src/app/globals.css`
- `src/index.css`, `styles/globals.css`, `app/styles/globals.css`

You're looking for a `:root { … }` block of CSS custom properties
(`--background`, `--foreground`, `--card`, `--primary`, `--secondary`,
`--muted`, `--accent`, `--destructive`, `--border`, `--input`, `--ring`, the
`--chart-*` / `--sidebar-*` tokens, `--radius`) and a matching `.dark { … }`
block. Values may be `hsl(...)`, `oklch(...)`, hex, or raw channels — keep them
exactly as the project wrote them.

Tailwind v4 projects usually keep the same `:root` / `.dark` blocks plus an
`@theme inline` mapping; you only need the `:root` and `.dark` token values,
not the `@theme` mapping.

## Step 2 — Assemble a valid theme CSS file

The publish endpoint parses `--name: value;` pairs out of a `:root { … }` block
and a `.dark { … }` block, and **requires both to be non-empty**. So the file
you publish must contain both.

- Copy the project's `:root` and `.dark` blocks into a standalone file
  (e.g. `project-theme.css`). Nothing else is required.
- **If the project has only a light `:root` and no `.dark`** (or an empty one),
  generate a dark variant before publishing — don't ship a theme with an empty
  dark mode. Reuse the `add-dark-mode` / `oklch-skill` approach: invert
  lightness while preserving hue/chroma so the dark set stays on-brand. Keep the
  same token names.
- Keep the token names shadcn-standard so the theme previews correctly on the
  card and applies cleanly for others.

Minimal shape:

```css
:root {
  --background: 0 0% 100%;
  --foreground: 240 10% 4%;
  --primary: 240 6% 10%;
  /* …the rest of the project's light tokens… */
  --radius: 0.5rem;
}
.dark {
  --background: 240 10% 4%;
  --foreground: 0 0% 98%;
  --primary: 0 0% 98%;
  /* …the rest of the project's dark tokens… */
}
```

## Step 3 — Name & tag it

- **Name** (required, ≤ 50 chars): infer from the project — the product/brand
  name from `package.json`, the repo, or the site title. Ask the user if it's
  ambiguous.
- **Tags** (optional): a few descriptors that match how people browse themes,
  e.g. `dark`, `minimal`, `neutral`, `vibrant`, `saas`. Pass comma-separated.

## Step 4 — Publish

```bash
21st publish-theme ./project-theme.css \
  --name "Acme" \
  --tags dark,minimal \
  --api-key 21st_sk_…            # or set TWENTYFIRST_TOKEN
```

The command prints the live theme URL (`https://21st.dev/community/themes/<slug>`).
Share it with the user.

## Updating vs re-publishing

- **Each `publish-theme` creates a NEW theme** (there's no upsert-by-slug like
  components have). Running it twice = two themes in the library.
- To change **name/tags/visibility** on an existing theme, edit it in place:
  `21st edit <theme-id> --type theme [--name "…"] [--tags a,b]`.
- To change the **colors**, publish a fresh file and remove the old one:
  `21st delete <theme-id> --type theme --yes` (soft-unpublish, reversible).

## When NOT to use this

- Syncing a component **library** to a Claude Design project → that's the
  built-in `/design-sync` skill, a different destination.
- Publishing a **component** (not a color theme) → use `21st-registry`.

© 21st-dev · Apache-2.0 · 21st-dev/skill

Similar skills

Everything for Frontend and UI →

From the same set7

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor