Skip to main content
Component publishing and metadata management accept a 21st login session or a secret API key (21st_sk_…). Theme/template publishing, editing, and deleting still require an API key from Settings → API keys, passed with --api-key or API_KEY_21ST.

Find or resume component work

21st components lists every accessible personal or Team component and every owned saved draft, draining all result pages by default. It closes with how many new drafts you may still start this hour, so the limit is visible before a publish runs into it. Drafts nobody returns to are reclaimed automatically after a day of silence. Use --status all|draft|published|private and --scope all|personal|team:<uuid> to narrow the inventory. The returned component:<id> and draft:<uuid> values are stable references. 21st open draft:<uuid> resumes an editable Studio draft. 21st open component:<id> creates or resumes a server-owned CLI Review revision from the retained published component code and demos. The live component stays unchanged until that revision is published. Each demo needs a fresh cover; Studio prioritizes the required covers and attempts optional videos best-effort in the background. --no-open creates or resumes the workspace and prints its editor URL without launching a browser. Use a local file when you already changed the source:
The ref prevents a same-slug component from being selected accidentally. Only the original component author can check out its code. A Team manager can still edit or unpublish a teammate’s component metadata by its exact stable ref. Checkout fails closed if retained source, dependencies, style, support files, or the default demo cannot be reproduced safely. In that case, use the local source command above to create the reviewed revision. A login session includes personal work and Teams the user can manage. A personal key is personal-only; a Team key is restricted to that Team. New CLI Review drafts persist their authenticated personal or Team/library scope, so Team filters and Team keys can resume them. Legacy proof-backed CLI drafts are recovered into the matching authenticated scope. An older unsigned draft whose scope cannot be proven may need to be recreated.

Look at a component without publishing it

21st render builds the component in a Studio workspace, photographs its demo, writes default.png (and default.mp4 with --video) into --out, then deletes the workspace — including on Ctrl-C. Nothing is published, nothing is listed, and no draft is left behind for you to find later. Use it to check a change before spending a publish on it. It borrows one Studio workspace while it runs, so it counts against the same draft limit as publishing; --keep leaves the workspace in place if you want to open it in Studio afterwards.

Manage a library

21st library lists every library you can manage — your own and those of teams where you are an owner or admin. update changes only what you pass: --name, --description, --display-name, --logo <file> or --logo-url <url>, --website, --github, --x, and --public / --private for the library’s public page. A library whose access is private has no public page, so --public is refused until the library itself is made public in Studio. Logos accept PNG, JPEG, WebP or SVG up to 2 MiB. Add --json to any of them for machine-readable output.

Publish a component

The CLI auto-detects the component name, slug, and tags from the source, and finds or synthesizes a demo file. A new slug or owned revision is dependency-checked, installed, and built before its draft opens in the dedicated CLI Review. Studio then generates the required cover and attempts an optional video in the background; publishing stays locked until every demo has a cover, but never waits for video. A cover you attach with --preview satisfies that on its own — it becomes the demo’s cover and no generated one is required. CLI Review is an overview: the component, its demos and their media, and the tags each state their status, with the matching form one click behind them. Above the preview, a switcher flips between the live demo, the captured cover, the video, and the component’s card as it appears in a listing. Access lives on the same screen — Public or Private, plus whether to submit the component to the catalog — so --visibility only sets the default. Publishing lands on the published component. Along with the Studio URL the CLI prints a review link. It opens the same screen in a browser that is signed into nothing — an agent’s browser, a phone, a colleague’s laptop — because it carries its own one-draft capability instead of relying on a session. The link opens once, expires in 24 hours, and dies the moment the draft is published or deleted; it can do nothing outside that draft. Treat it like the draft itself: whoever holds it can finish this publish. To update local source, pass its stable --component component:<id> ref; this creates a pending revision and sends it through the same CLI Review instead of updating the live component directly. Agents and scripts can complete the same review without opening Studio:
--prepare never publishes. It waits for revision-bound automatic media and optionally downloads it with --media-dir. --auto publishes only after every required cover is ready; a cover attached with --preview counts as ready on its own, so --auto --preview neither waits for nor fails on capture. --wait-video additionally requires a successful video. Both modes are CLI-only and never open a browser.

One draft, many edits

--draft sends the file you pass into that draft before anything else, so fixing the component and running the command again keeps working in the same draft instead of creating a sandbox per edit:
The draft re-signs its revision and captures the cover and video again, exactly as an edit made in the review screen does. Anything the new code imports is installed into the draft first, so adding a dependency between runs works. Media you uploaded yourself is kept. A push carries the whole set: repeat --demo to add demos, drop one from the command to remove it, and edited --description, --name or --tags travel with the code. The slug and the registry are fixed when the draft is created, since they decide what it publishes as. The component slug and the set of demos are fixed when the draft is created, so a push changes code only; add --no-push to resume a draft without touching its source, for example to finish a publish that was interrupted. With --json, stdout carries exactly one JSON document (state, and on success component_id, url, install_ref); all progress moves to stderr. Exit codes are stable for scripting: 0 published, 1 generic failure, 2 draft handed off without publishing (CI), 3 auth, 4 rate limited, 5 build failed, 6 cover/media not ready, 7 conflict, 130 interrupted. To read a draft the same way without publishing, 21st draft <draft:uuid> prints its state, editor URL and per-demo media states; --watch streams every transition until the draft publishes, fails or is deleted. Common flags: See Publishing → Quick Start for the full flow and requirements.

Controls come from the demo file

A demo that declares a module-level const settings = { … } and takes it as props publishes with a live controls panel next to its preview, and visitors copy code carrying the values they tuned. The CLI needs no flag for it: the defaults are read from the source you publish. Labels and ranges are edited afterwards from the component’s Edit dialog without a re-publish, but which knobs exist and what they start at change only by publishing again. See Demo Controls.
The current CLI Review command sends one self-contained component source file and one demo. Additional local files, 21st.json, and registry dependencies are not supported for either a new component or an owned revision yet.

Review the CLI draft before publishing

The build check cannot detect every runtime, interaction, or theme problem. Before publishing, confirm that the build passed, every imported package is declared in the nearest package.json, and every demo works in the right-side live preview. Test meaningful states in both light and dark themes, including that the primary color resolves correctly. Use semantic Tailwind utilities such as bg-primary and text-primary-foreground. For custom CSS, use Tailwind v4 variables such as var(--color-primary). Do not write oklch(var(--primary)) or hsl(var(--primary)): projects can represent raw tokens differently, making otherwise valid CSS render the wrong color in Studio. Use an opacity utility such as bg-primary/20, or color-mix() with var(--color-primary). The CLI rejects these known non-portable raw-token wrappers before it creates a draft. Studio starts media generation as soon as the draft is ready. It prioritizes the required cover, which must be ready before publishing. The optional video is best-effort in the background: publishing never waits for it and includes it only if it is ready. An interaction video is accepted only when a click, press, typing, keyboard, or scroll beat produces a visible result. Give interactive controls stable semantic selectors such as an id, native role, or data-slot; a missing selector or a visually unchanged interaction is retried once and then fails closed instead of attaching a cursor-only clip. You can replace either generated asset manually. If the component is blank, throws, has unresolved dependencies, or renders the wrong primary color, fix the source in CLI Review and save it. Studio signs the new source revision, invalidates every cover and video from the old revision, and queues fresh media with the required cover first. Publishing stays blocked until that new cover is ready or you upload a replacement. An auto-generated cover does not replace the visual and interaction review.
Private personal components are visible only to you. Publishing privately to a Team library requires an active Team plan and owner or admin access.
Publishing and catalog review are separate. A Published component is available by link and on your profile. Submit it for featuring only when it is ready:

When a publish fails

A failed publish prints what went wrong, which step it happened in, and the build output itself:
Fix your source for a build error and publish again. For a temporary failure, publish again as-is. Quote the request ID if you contact support: it identifies the exact request on our side. The JSON body of a failed POST /api/v1/components/publish carries the same information: error (the code above), message, retryable, request_id, and details with stage, demo_slug or dependency, and output. Retry only when retryable is true. The rest will fail the same way until the source changes.

Publish a theme

The CSS file must contain both :root and .dark blocks.

Publish a template

Submits a template listing for moderation (it lands as a draft). For paid templates, set --price and a --buy-url checkout link. See Selling & promotion.

Edit your content

--type is component, theme, or template. Component metadata edit and delete accept a saved 21st login session or API key. A Team manager can manage a teammate’s component metadata, but only its original author can check out a code revision. Theme/template management still requires an API key. Editable fields differ per type (templates use numeric tag ids and have no visibility field).

Unpublish or delete

--yes is required to confirm. For components and themes this unpublishes (sets visibility to private / clears the published date). For templates it is a permanent delete. Deleting a draft permanently removes its unpublished sandbox and code.