CLI reference
One command line, your whole design system.
The synthesisui CLI brings a system into any project and hands your coding agent everything it needs to build on-system. No install - it runs with npx.
Start here
Run this in any project you already have. It reads your files, writes none of them, and needs no account.
npx synthesisui@latest doctorIt counts every design value written by hand and, once a system is installed, names the token your own system already has for each one. What it reports →
Free
Hosted AI
Free · no account, nothing sent anywhere
adopt
Turn the design system you ALREADY have into a contract your coding agent follows - without touching a line of your CSS.
synthesisui adopt [--write] [--tokens <path>] [--slug <name>]`init` installs our tokens, which is why it ends in a one-time setup you have to do by hand. If your project already declares its own custom properties, none of that applies: they are in `:root` and already painting the screen, and what is missing is not code but the contract - the file your agent reads before it writes UI. So adopt writes no CSS at all. It reads your stylesheets, describes your system in `_synthesisui/`, and adds a managed block to CLAUDE.md pointing at it. Your tokens keep your names, your files are not rewritten, and `clean` removes every trace. It is a dry run by default: nothing lands on disk until you pass `--write`.
Options
- --write
- Actually create the files. Without it, adopt only shows what it would do.
- --tokens <path>
- Read one stylesheet instead of searching - for tokens somewhere the scan does not reach.
- --slug <name>
- Name the system yourself. The default is guessed from your token prefix, then your package name.
Examples
A dry run. Nothing lands on disk until you ask.
$ npx synthesisui@latest adopt── Adopt ─────────────────────────────────────────────────────────
Reading your system … 3 stylesheets, 29 tokens found
colour 19
spacing 6
radius 4
from src/app/globals.css (29)
Would create (nothing written yet):
_synthesisui/ds/acme/system.json your system, described
_synthesisui/ds/acme/GUIDE.md what your agent reads
CLAUDE.md a managed block pointing at it
Your stylesheets are not touched. Nothing outside
_synthesisui/ is written, and `clean` removes all of it.Then `doctor` measures your code against your own vocabulary.
$ npx synthesisui@latest adopt --writeWhen the scan does not reach where your tokens live.
$ npx synthesisui@latest adopt --tokens src/styles/theme.cssimport
Read the app you already have and turn it into your design system - v1 mirroring your own values exactly.
synthesisui import [--dir <path>] [--dry] [--name <name>] [--census <path>]The entrance for somebody who already shipped something. It takes a CENSUS of your project: every colour, radius, spacing and font, ranked by how often it repeats, plus the tokens you already declare - all arithmetic, no inference, the same scan the doctor runs. `--dry` writes that census to `_synthesisui/census.json` and sends nothing, so you can read the payload before it leaves the machine. Without `--dry` (and after `login`) it becomes a design system on your account, and the promise there is fidelity: v1 carries YOUR values under YOUR names, nothing normalised, nothing improved, scoring exactly as well or badly as your app does. That honesty is what makes the v2 it proposes afterwards worth approving. A role your project never names is left neutral rather than guessed, and the report says how many. An agent can annotate the census with judgement a parser cannot make - which grey is the real grey, which family is the display voice - and send that back with `--census`; any value it invents that your code does not contain is dropped.
Options
- --dry
- Take the census and write it to disk. Nothing is sent and no account is needed.
- --dir <path>
- Read this folder instead of the current one. In a monorepo this is the important one: point it at the package that holds your vocabulary.
- --census <path>
- Send a census file you (or your agent) already annotated instead of taking a fresh one.
- --name <name>
- Name the system without being asked. At a terminal the command offers a name and waits; scripts and CI should pass this.
Examples
See what your code says before anything leaves your machine.
$ npx synthesisui@latest import --dry── What your project says ──────────────────────────────────────── next · react · tailwind 2 files · 12 distinct design values 10 color · 5 radius · 4 spacing #ffffff color, 3× in 2 files 12px radius, 3× in 2 files #71717a color, 2× in 2 files Written to _synthesisui/census.json Nothing was sent. Read the file, then run it without --dry.
Needs `login` first - this is the moment something leaves the machine. It asks what to call the system before creating anything.
$ npx synthesisui@latest importA monorepo has one system and several consumers. Born from the package that holds the vocabulary, then measure each app against it with `doctor apps/<name>`.
$ npx synthesisui@latest import --dir packages/ui── This root holds several projects ──────────────────────────────
3 apps (apps/web-admin, apps/web-dashboard, apps/web-review) - and this
census is the average of all of them.
That is a fine DIAGNOSIS and a poor system: a light app and a dark one
average into a palette that is neither.
The shape that works, if your vocabulary is shared:
synthesisui import --dir packages/ui the system comes from here
synthesisui doctor apps/web-dashboard how far this one is from itconnect
Wire your agent to the system: the check as a hook, the system as tools, and a contract that stops repeating itself.
synthesisui connect [--no-hook] [--no-mcp]Three layers, and only the first one guarantees anything. The HOOK runs the check after every file your agent writes, so whether it happens stops being the agent's decision - measured on a real build, an instruction to run the check by hand sat at line 24 of a 44-line file and was ignored. The TOOLS let it ask this system what a value is called instead of guessing. And the CLAUDE.md block, seeing the hook installed, stops demanding a check that already happened, because two places asking for the same thing is drift in the instructions. Both config files belong to you: every write is a merge, running it twice changes nothing, and a file it cannot parse is refused rather than replaced. Restart your editor session afterwards - hooks and tools are only read at startup.
Options
- --no-hook
- Skip the hook. The tools and the contract still land.
- --no-mcp
- Skip the tools. The hook and the contract still land.
Examples
Both layers, merged into whatever config is already there.
$ npx synthesisui@latest connect── Connected ─────────────────────────────────────────────────
✓ .claude/settings.json the check now runs after every write
npx synthesisui@0.16.13 hook
✓ .mcp.json four tools, so the agent can ask instead of guess
✓ CLAUDE.md rewritten for what is installed
Reopen your editor session - both are read at startup.mcp
The design system as tools your agent can query. Local, no account, no network.
synthesisui mcpStarted by your editor, not by you - `connect` registers it. Four tools: check_file measures one file and names the token this project already has for every literal; find_token answers what the system calls a value, and refuses when nothing holds it; list_components is the live catalogue with what each component is for; add_component materializes one as real code. It reads the system already installed in the project, so it works offline and needs no account.
Examples
You never run `mcp` by hand. This registers it - then restart the session.
$ npx synthesisui@latest connecthook
The check, run by your editor after every write rather than remembered.
synthesisui hookStarted by your editor, not by you - `connect` installs it. It reads the file that was just written and reports the token this project already has for anything hardcoded, plus any --ds- name the system does not declare. It never blocks: refusing an edit makes the check an adversary, and an adversary gets disabled within a day. And it is silent when there is nothing to say, because a hook that speaks on every edit is noise, and noise is what gets a hook removed.
Examples
You never run `hook` by hand. This installs it - then restart the session.
$ npx synthesisui@latest connectdoctor
Audit any repo for drift - every design value written by hand, and the token your system already has for it.
synthesisui doctor [paths…] [options]The only command that needs nothing: no account, no install, no network. It reads your files and writes none of them. It does not need a system from us either: if your project declares its own tokens - `--acme-color-primary` in `:root`, Tailwind v4's `@theme`, anything at the root - it measures your code against YOUR vocabulary and names the drift with your own words. With one of our systems installed it also reports where the code overrules a component the system defines, and where the system contradicts itself. With no tokens anywhere it still counts the distinct design values written by hand, which is the number worth knowing before anything else.
Options
- --verbose
- Every finding, file by file. The default is a summary.
- --strict
- Exit 1 when THIS repo has drift or overrides - for CI.
- --strict-system
- Also exit 1 when the design system itself is inconsistent.
- --laws
- Show every usage law, not just the busiest components.
Examples
Nothing installed yet? It still has something to tell you.
$ npx synthesisui@latest doctor── Doctor ────────────────────────────────────────────────────────
No system installed - 1 file read
4 distinct design values are written by hand here.
No design system is installed, so none of them has a name yet.
Give them one:
npx synthesisui@latest init --ds <slug>With a system installed, every loose value gets named.
$ npx synthesisui@latest doctor── Doctor ────────────────────────────────────────────────────────
Ember v22 - 87 tokens, 3 files read
Token coverage ░░░░░░░░░░░░░░░░░░░░░░░░ 0%
0 from the system, 6 by hand
6 values by hand · 5 already have a name
4 overrides · 4 left the system
Where to start
1. the 4 overrides that left the system 4 places
2. #f5f2f6 → --ds-color-obsidian-100 2 files (cheap)
3. #a79eb2 → --ds-color-obsidian-300 2 files (cheap)In a monorepo, point it at what you actually ship.
$ npx synthesisui@latest doctor apps/web packages/ui --verboseExits 1 when this repo drifts. Drop it in CI.
$ npx synthesisui@latest doctor --strictlogin
Connect the CLI to your account (device flow).
synthesisui loginOpens a short device-code flow so the CLI can reach your private systems and the hosted AI commands. Public gallery systems don't need it.
Examples
$ npx synthesisui@latest login→ opening https://www.synthesisui.com/device?user_code=WXYZ-1234 (code pre-filled) ✓ logged in as you@company.com
init
Write _synthesisui/config.json (framework target + folders) and optionally bring a system in.
synthesisui init [options]Bootstraps a project: records where pages and components live and which framework you target, so later commands need no flags. With --ds it also pulls that system in right away (tokens + rules + philosophy + CLAUDE.md).
Options
- --styles <css|tailwind>
- How materialized components are styled (default: css).
- --target <next|general>
- Framework target (default: next).
- --pages-dir <dir>
- Where generated pages go (default: app).
- --components-dir <dir>
- Where components live (default: components).
- --ds <slug>
- Bring this system in immediately.
Examples
$ npx synthesisui init --styles tailwindbootstrap and bring a system in, one step.
$ npx synthesisui init --styles tailwind --ds halogenlist
List the published design systems.
synthesisui listExamples
$ npx synthesisui listember v13 Warm obsidian, incandescent gradients halogen v11 Cool, clinical, high-contrast …
add
Materialize a design system into _synthesisui/ds/<slug>/ (tokens, recipes, GUIDE, CLAUDE.md).
synthesisui add <slug> [options]Brings the whole system into your project: tokens.css + theme.css, the recipe catalog, rules.md / philosophy.md (when authored) and a GUIDE.md the agent reads. Public systems need no login.
Options
- --version <n>
- Pin a version (default: latest).
Examples
$ npx synthesisui add halogen$ npx synthesisui add halogen --version 3$ npx synthesisui add halogen✓ Halogen v11 → _synthesisui/ds/halogen/ ✓ CLAUDE.md updated - the agent now knows the system
use
Print a ready-to-paste prompt for your coding agent to build/modify UI on-system.
synthesisui use <slug> "<intent>"Reads only local state (no network) and prints a prompt describing the task on-system: which files to read first, the data-ds scope, the styling contract and where files go. Works for both building new UI and modifying existing UI. Pipe to pbcopy to copy just the prompt.
Examples
$ npx synthesisui use halogen "a pricing section with three tiers and a highlighted plan"modifying existing UI - it locates the file first, then changes only what's needed.
$ npx synthesisui use halogen "make the card shadow softer in components/StatCard.tsx"template
Materialize a whole page from a system template into your project.
synthesisui template <slug> <name>Codegens a deterministic page from the system's templates - the .tsx plus co-located scoped CSS (responsive + the CSS-only hamburger). Refine it in place; it stays on-system. (Formerly `page`; the old name still works.)
Options
- --target <next|general>
- Override the project target.
- --as <name>
- Name the output (templates/<name>/) - multi-page safe: two landings never collide.
- --out <path>
- Override the page file path (advanced; default: templates/<name>/<name>.tsx).
Examples
$ npx synthesisui template halogen dashboard-sidebara second landing page that won't clobber the first.
$ npx synthesisui template halogen landing --as landing-homecomponent
Bring one component (recipe + compiled CSS) from a system into the project.
synthesisui component <slug> <name>Granular 'bring specific': writes a single component under _synthesisui/ds/<slug>/components/ - handy for one you refit or created on the platform. Its styles reference the DS tokens, so install the system (add <slug>) for tokens.css to resolve.
Options
- --version <n>
- Pin a version (default: latest).
Examples
$ npx synthesisui component halogen pricing-tier$ npx synthesisui component halogen pricing-tier✓ pricing-tier → _synthesisui/ds/halogen/components/pricing-tier.{json,css}upgrade
Move an installed system to the latest version and get a migration brief for your agent.
synthesisui upgrade <slug> [options]Re-materializes the artifacts under a new v<n>/ (the old folder stays, for rollback and diff), regenerates the components the CLI itself wrote, and writes UPGRADE.md - a deterministic list of what changed, breaking items first. Hand that file to your coding agent. A variant that never rendered anything is housekeeping, not a breaking change, and the brief says so.
Options
- --force
- Rewrite UPGRADE.md even with no version gap left - useful when the brief on disk is stale.
- --from <n>
- With --force: which older snapshot on disk to diff from.
Examples
$ npx synthesisui@latest upgrade ember↑ Ember v18 → v22 (kept v18/ for rollback) rules.md → 7 rules (read these first) ── Upgraded ember: v18 → v22 ───────────────────────────────────── No breaking changes detected. The migration brief is at _synthesisui/ds/ember/UPGRADE.md
clean
Strip create-next-app boilerplate so the system has a clean surface to land on.
synthesisui clean [--force]Dry run by default: it lists what it would remove and touches nothing. The starter's own CSS fights a design system for the same selectors, and its leftovers are the single biggest source of a page that renders unstyled after install.
Options
- --force
- Apply the changes. Without it, dry run.
Examples
See what it would remove, remove nothing.
$ npx synthesisui@latest clean$ npx synthesisui@latest clean --forcerequest
The queue of what your agent needed and the system refused to invent.
synthesisui request [component|token] [--done <id>]When the agent hits a gap - a component the catalogue lacks, a value with no token - the contract makes it file the gap instead of inventing, with the use case and what it considered already written. Run bare to read the queue; close a request once you have authored it or decided against it. Nothing expires on its own.
Options
- --name
- What the agent would call it.
- --for
- The use case, concretely.
- --considered
- Catalogue entries considered, and why each did not fit.
- --value
- Token requests: the concrete value.
- --done <id>
- Close a request, by hand, on purpose.
Examples
Read the queue. Also printed by doctor.
$ npx synthesisui@latest request$ npx synthesisui@latest request component --name "keyboard-hint" --for "a drawn key cap in a shortcut legend"$ npx synthesisui@latest request --done 1xhueosync
Send the local record - checks, fixes, open requests - to your system's dashboard.
synthesisui syncThe hook writes a ledger on your machine and never touches the network. This is the one command that ships it, by hand, to the overview page of a system you own. Re-running is free: the server dedupes events and treats the request queue as a snapshot, so the local files stay the source of truth.
Examples
After a working session, or from CI after a merge.
$ npx synthesisui@latest syncHosted AI · login required, spends credits
generate
login requiredGenerate a token-only component recipe for your system with hosted AI.
synthesisui generate "<description>"Our AI generates a new component as a validated token-only recipe (anti-hallucination by construction) and writes it under _synthesisui/ds/<slug>/generated/. It wears the system automatically.
Options
- --ds <slug>
- Target system (default: the installed one).
- --name <name>
- Preferred component name.
Examples
$ npx synthesisui generate "an upgrade banner with a title, message and a primary CTA"✓ upgrade-banner generated (recipe + css)
→ _synthesisui/ds/halogen/generated/upgrade-banner.{json,css}advise
login requiredGet engagement-pattern proposals tailored to your product (hosted AI).
synthesisui advise "<value proposition>"Describes your product and gets back proposed engagement patterns to consider - it proposes, never auto-applies.
Examples
$ npx synthesisui advise "habit-building app for tracking personal finances"refit
login requiredAdapt a component you already have INTO your system, and get the code back.
synthesisui refit <file> [--ds <slug>]Point it at a file you wrote (or one an agent wrote for you) and it comes back re-expressed in your tokens, keeping the structure and the behaviour. Uses hosted AI, so it needs login and spends credits - the deterministic commands never do.
Examples
$ npx synthesisui@latest refit components/pricing-card.tsxSeveral systems installed? Name the one to fit into.
$ npx synthesisui@latest refit app/hero.tsx --ds vesperGlobal options
These work on any command.
- --registry <url>
- Registry URL (or set SYNTHESISUI_REGISTRY_URL).
- --dir <path>
- Consumer project root (default: current dir).
- --version <n>
- Install a specific version (default: latest).
- -h, --help
- Show help.