
21st-registry
Publish a React component to the user's team library on 21st.dev so teammates can install it with a single command, or install an existing one. Triggers when the user says things like "publish/share/upload this to 21st", "залей в наш регистр", "опубликуй компонент", "share with team", "make this reusable", "install our Button", "use the team button".
- Installs
- 201
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/21st-dev/registry --skill 21st-registry- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads 21st-registry automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Publish & install components in the 21st team library
Use this skill in two directions: publishing a component for the team, and installing one the team already shared.
Pre-flight (always)
- Check auth:
API_KEY_21STenv is set, or the registry CLI has saved credentials. If neither — tell the user to runnpx @21st-dev/registry loginonce. Don't try to log them in yourself. - The CLI is
@21st-dev/registry. Don't reinvent — use it.
Publishing a component
Decide visibility — default to unlisted in a registry
| User says… | Visibility |
|---|---|
| "share with team", "залей нам", "publish internally", default for any unqualified ask | unlisted in the selected/default registry (no visibility flag needed) |
| "share publicly via link / on my profile, but don't list it in the library" | --unlisted |
| "publish publicly", "make it public on 21st" | --public |
| "restrict to the registry team", "private team draft" | --private |
Never use --public without explicit user instruction. Public components go through admin moderation and appear in the 21st library. --unlisted is the safe option when the user wants a shareable URL but doesn't want a library listing.
Standard publish
The CLI's positional file path triggers auto-detection — name from the default export, slug from the filename, tags from imports, demo auto-found or synthesised. So in 95% of cases this is enough:
npx @21st-dev/registry ./path/to/Component.tsx \
--to default \
--description "1-2 sentences about what it does and when to use it"
Flag reference
| Flag | When to use |
|---|---|
--name "Display Name" | Override the auto-detected name. Default is humanised version of the default-export name. |
--description "…" | Required. 10+ chars. Write a real description — what it does and when to use it. Never fabricate; if you don't know, ask the user. |
--tags "form,input,validation" | 1-5 lowercase tags. Default: detected from imports (lucide-react → "icon", framer-motion → "animation", etc). Only override if the auto-detected ones miss the point. |
--slug my-button | Override the URL slug. Default: kebab-case from name. |
--demo ./Component.demo.tsx | Demo file. Auto-detected by these patterns: {Component}.demo.tsx, demos/{slug}.tsx, demos/default.tsx. If none exist, the CLI synthesises a trivial <Component /> demo automatically — fine for v1, but a real demo gives a much better preview. |
--preview ./preview.png | Optional. The team library uses a live iframe preview; a static image is only needed if you want a snappy thumbnail. |
--to <registry-slug> | Target a specific registry in the authenticated team (e.g. --to default). If omitted, the server uses the team's first/default registry. |
--public / --unlisted / --private | Override component visibility. |
What the user gets back
✅ https://21st.dev/community/components/{username}/{slug}
Install in another project:
npx @21st-dev/registry add @{username}/{slug}
Updating an existing component
Same command, same slug → upsert. The CLI prints "Updated" instead of "Published". No version flag needed; teammates always get the latest.
If the user says "I want a NEW component, not an update" but slug collides — confirm with the user before overwriting; suggest changing --slug.
Installing a component
Two address formats are accepted:
@team-slug/component-slug— install from a team registry (preferred for team-shared)@username/component-slug— install from a user's personal/public components
npx @21st-dev/registry add @acme/animated-button
# or
npx @21st-dev/registry add @serjobas/animated-button
The CLI:
- Fetches the registry JSON and component file (server resolves
@handleagainst team-slug first, then username) - Writes it to the project (
components/ui/{slug}.tsxby default) - Runs
pnpm/npm/yarn/bun addfor any npm dependencies - If it depends on other 21st components, prints them — install with
addseparately
For shadcn directly, public/unlisted components can use the plain registry item URL:
npx shadcn@latest add "https://21st.dev/r/acme/animated-button"
For repeat installs or private components, register the 21st registry in the consumer project's components.json and use a Bearer token:
{
"registries": {
"@YOUR_NAMESPACE": {
"url": "https://21st.dev/r/acme/default/{name}.json",
"headers": {
"Authorization": "Bearer ${API_KEY_21ST}"
}
}
}
}
Then install with the stock shadcn CLI:
npx shadcn@latest add @YOUR_NAMESPACE/animated-button
@YOUR_NAMESPACE is just the local alias from components.json; choose any clear slug. Do not commit real API keys into components.json unless the user explicitly wants that local file to contain a personal key.
Flags:
--force— overwrite existing file--no-install— skip npm install step (just write files)--dir PATH— install into a different project directory
Searching the team library
When the user wants a component but doesn't know the exact name:
npx @21st-dev/registry search "<query>"
Default scope is team (your team's library). Use --scope mine for just your own, --scope public for the public library.
Always search before publishing if there's a chance a similar component already exists. Don't add duplicates to the team library.
npx @21st-dev/registry search "button" --scope team
# Prints list with @user/slug refs you can pass to `add`.
Managing teams & registries
View, create, and edit teams and registries from the CLI (no deletion — that
stays in the web Studio). Every subcommand accepts --json; prefer it when
you need to parse the output. Teams are addressed by slug with --team <slug>
(default: the team the API key belongs to).
# Inspect before acting
npx @21st-dev/registry team list --json # all teams: slug, role, default
npx @21st-dev/registry team info [team] # members + pending invites
npx @21st-dev/registry registry list --team <slug> --json
# Create
npx @21st-dev/registry team create "<name>" [--description TEXT]
npx @21st-dev/registry registry create "<name>" [--slug SLUG] [--description TEXT] [--team SLUG]
# registry slug is auto-derived from the name if --slug is omitted
# Edit
npx @21st-dev/registry team edit [team] --name TEXT --description TEXT # owner only
npx @21st-dev/registry registry edit <slug> --name TEXT --description TEXT
# Invite a collaborator by email
npx @21st-dev/registry team invite <email> [--team SLUG]
Typical flow before publishing a new component group: registry list --json
to see what exists → registry create "Marketing blocks" if needed →
publish --to marketing-blocks.
Hard rules for agents
- ❌ Never use
--publicwithout an explicit "publish publicly" from the user. - ❌ Never fabricate a description. Ask the user, or read the code carefully.
- ❌ Never include API keys, env values, or hardcoded internal URLs in the component file you publish.
- ❌ Never publish a file with unsaved edits — flush first.
- ✅ Always search before publishing if a similar component might already exist.
- ✅ Always add a useful demo file with realistic props if you can; only fall back to the auto-synthesised one as a last resort.
Common mistakes to avoid
- Demo imports the component via a wrong path. The CLI auto-rewrites relative imports (e.g.
import X from "../component") to@/components/ui/{slug}before upload — so write demos with relative imports to the user's source file, not aliases. The CLI will sort it out. - Slug doesn't match between publishes. If the user renames the file, the auto-derived slug changes and you'll create a duplicate. Pass
--slugexplicitly when re-publishing under a stable name. - Component lacks a default export. This will fail with a clear error — refactor the component to
export default function ComponentName(...)first.
FAQ
What does the 21st-registry skill do?
Publish a React component to the user's team library on 21st.dev so teammates can install it with a single command, or install an existing one. Triggers when the user says things like "publish/share/upload this to 21st", "залей в наш регистр", "опубликуй компонент", "share with team", "make this reusable", "install our Button", "use the team button".
How do I install 21st-registry?
Run npx skills add https://github.com/21st-dev/registry --skill 21st-registry in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/21st-registry/ (personal) or .claude/skills/21st-registry/ (project).
Which AI agents can use 21st-registry?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is 21st-registry safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains 21st-registry?
It is published by 21st-dev in 21st-dev/registry. It has 201 recorded installs.
Popular frontend & design skills
setup-matt-pocock-skills
mattpocock/skills
Configure this repo for the engineering skills: set up its issue tracker, triage label vocabulary, and domain doc layout. Run once before first use of the other engineering skills.
frontend-design
anthropics/skills
Guidance for distinctive, intentional visual design when building new UI or reshaping an existing one. Helps with aesthetic direction, typography, and making choices that don't read as templated defaults.
hyperframes-animation
heygen-com/hyperframes
All animation knowledge for HyperFrames — atomic motion rules, multi-phase scene blueprints, scene transitions, broader motion-design techniques, AND the seven runtime adapters (GSAP default, plus Lottie, Three.js, Anime.js, CSS keyframes, Web Animations API, TypeGPU). Use for any motion or animation task: pick 2-4 rules and compose, or load a blueprint, or look up runtime-specific API (e.g. GSAP eases / Lottie player / Three.js mixer). Also covers auditing an existing composition's choreography (animation map) and 24 named text-animation effects. HyperFrames-native: single paused timeline, seek-safe, deterministic.
prototype
mattpocock/skills
Build a throwaway prototype to answer a design question. Use when the user wants to sanity-check whether a state model or logic feels right, or explore what a UI should look like.
hyperframes-core
heygen-com/hyperframes
The HyperFrames composition contract — build one renderable project. Use for composition structure, the data- timing attributes, class="clip", tracks, sub-compositions, variables, framework-owned media playback, deterministic-render rules, and validation. Read before writing composition HTML.
vercel-react-best-practices
vercel-labs/agent-skills
React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.