Particles UIDOCSDESIGN DECISION INFRASTRUCTUREStudioCLIMCP
Getting startedStudioTokensToken architectureThemes & modesChanges & governanceBranches & reviewsDesign documentationFigma pluginCLIConnect AI agentsMCP playbookWebhooks & CI/CDSecurityPrivacyTerms
Docs / CLI / CLI

CLI

The particles command-line tool lets you pull tokens into your codebase, export CSS, push existing token files, and automate syncing in CI. Developers use it to consume tokens; designers and admins can also push token files to bootstrap or migrate a project.

Installation#

Available on npm as @particlesui/cli.

terminal
npm install -g @particlesui/cli
# or
pnpm add -g @particlesui/cli
# or run without installing
npx @particlesui/cli <command>

Authentication#

The CLI authenticates via OAuth device flow — the same approach used by gh auth login. Run the command below and approve the request in your browser.

terminal
particles auth login

Your session token is stored in the OS config directory:

terminal
# macOS
~/Library/Application Support/particles-ui/auth.json

# Linux (XDG_CONFIG_HOME takes precedence if set)
~/.config/particles-ui/auth.json
# or: $XDG_CONFIG_HOME/particles-ui/auth.json

# Windows
%APPDATA%\particles-ui\auth.json

Check the current auth state at any time:

terminal
particles auth status
particles auth logout

Init#

Run particles auth login first, then particles init in your project root. The command walks you through an interactive setup:

StepWhat you choose
OrganizationSelect from your organizations fetched from the platform.
ProjectSelect from the projects in that organization.
Export formattailwind-v4, css, scss, style-dictionary, dtcg, json, ts, js, or flutter (Dart class).
Output directoryDirectory where the generated file will be written (e.g. src/styles).
File nameFile name without extension (e.g. tokens). Extension is derived from format.

After the prompts, the CLI fetches the initial token file from the platform and writes it to disk, then creates particles-ui.json:

particles-ui.json
{
  "projectId": "018fde70-0000-7000-8000-000000000001",
  "organizationId": "018fde70-0000-7000-8000-000000000002",
  "format": "tailwind-v4",
  "outputDestination": "src/styles/tokens.css"
}

For CI or scripted setup, skip the prompts with flags:

terminal
particles init --yes \
  --org-id <id> \
  --project-id <id> \
  --format tailwind-v4 \
  --output-dir src/styles \
  --file-name tokens

Commands#

token-studio sync

Fetch tokens and write them to outputDestination (configured during init). Works like npm install — by default it pulls the latest published release. If no releases exist yet, it falls back to the branch HEAD. This command replaces the entire output file — it is the source of truth, not a partial update.

terminal
# Pull latest release (default — recommended for production)
particles token-studio sync

# Pull from a branch HEAD (useful during active development)
particles token-studio sync --branch rebrand-2025

# Pin to a specific release snapshot
particles token-studio sync --version 1.2.3

# Sync and fail CI if any contrast pairs fail WCAG AA
particles token-studio sync --wcag-level AA

# Resolve from a release channel (default: stable)
particles token-studio sync --channel beta

# Scope to one platform in a multi-level project
particles token-studio sync --platform-id <id>

Releases carry a channel (stable or beta), chosen at publish time in the Studio. --channel filters which channel sync resolves against — CI stays pinned to stable while a beta channel soaks upcoming changes.

src/styles/tokens.css (written by sync)
@import "tailwindcss";

@theme {
  --color-blue-100: oklch(0.93 0.03 245);
  --color-blue-500: #3b82f6;
  --color-neutral-50: oklch(0.98 0 0);
  --color-neutral-900: oklch(0.09 0 0);
  --color-background: var(--color-neutral-900);
  --color-primary: var(--color-blue-500);
  --spacing-1: 0.25rem;
  --radius-md: 0.5rem;
}
i

Token variables are sorted alphabetically by type group, then by group path and name (with numeric-aware ordering so 100 sorts before 200 and 1000), matching the order you see in the Studio token list.

token-studio export

Export resolved tokens in a chosen format — useful for piping into other tools or generating multiple artifacts from one source of truth.

terminal
# Tailwind v4 CSS (default)
particles token-studio export --format tailwind-v4

# Write to a file instead of stdout
particles token-studio export --format css --output ./styles/tokens.css

# Export from a specific branch
particles token-studio export --format scss --branch rebrand-2025

# Pin to a published release snapshot
particles token-studio export --version 1.2.3 --format tailwind-v4

# TypeScript theme object — drops into MUI createTheme() or styled-components ThemeProvider
particles token-studio export --format ts --output ./src/theme.ts

# Plain JS theme object (same shape, no type annotations)
particles token-studio export --format js --output ./src/theme.js

# Other formats
particles token-studio export --format style-dictionary
particles token-studio export --format dtcg
particles token-studio export --format flutter --output lib/tokens.dart
particles token-studio export --format json

# Pipe into another tool
# (.tokens // .) handles both shapes: a branch with modes exports { tokens, modes }
particles token-studio export --format json | jq '(.tokens // .)[] | select(.type == "color")'

The ts and js formats emit a single named export grouped by token type — colors, spacing, fontSize, radii, shadows, and so on — with groupPath nested underneath. Composition tokens are emitted as parsed nested objects. The TS variant appends as const and an export type Theme = typeof theme alias so consumers get autocomplete for every token path. Semantic tokens emit fully resolved values (a snapshot) since JS objects can't reference siblings cleanly.

src/theme.ts (excerpt)
export const theme = {
  colors: {
    brand: {
      primary: { "500": "#3b82f6", "600": "#2563eb" },
    },
    background: { default: "#ffffff" },
  },
  spacing: { sm: "8px", md: "16px" },
  fontSize: { base: "16px" },
  radii: { md: "8px" },
  shadows: { sm: "0 1px 2px rgba(0,0,0,0.08)" },
} as const

export type Theme = typeof theme
styled-components — drop in directly
import { ThemeProvider } from 'styled-components'
import { theme } from './theme'

export function App({ children }) {
  return <ThemeProvider theme={theme}>{children}</ThemeProvider>
}
MUI — spread into createTheme()
import { createTheme, ThemeProvider } from '@mui/material'
import { theme as tokens } from './theme'

const muiTheme = createTheme({
  palette: {
    primary: { main: tokens.colors.brand.primary['500'] },
    background: { default: tokens.colors.background.default },
  },
  typography: { fontSize: parseInt(tokens.fontSize.base) },
  shape: { borderRadius: parseInt(tokens.radii.md) },
})

export function App({ children }) {
  return <ThemeProvider theme={muiTheme}>{children}</ThemeProvider>
}

token-studio push

Push a local token file into a project branch — useful for bootstrapping a new project from an existing design file, migrating a legacy token library, or scripting bulk token updates from CI. Targets main by default; use --branch to push to a feature branch.

i

Push requires the tokens:write permission, which is granted to Admin and Designer roles. Developer accounts have read-only CLI access and cannot push.

terminal
# Preview changes without applying them (dry run)
particles token-studio push --file ./tokens/globals.json --dry-run

# Apply changes — JSON is auto-detected (DTCG, Tokens Studio, Style Dictionary, or Particles)
particles token-studio push --file ./tokens/globals.json

# Push to a feature branch instead of main
particles token-studio push --file ./tokens/globals.json --branch rebrand-2025

# Push a CSS file (custom properties are parsed automatically)
particles token-studio push --file ./styles/tokens.css

# Push SCSS variables
particles token-studio push --file ./styles/_tokens.scss

# Push a TypeScript theme object (evaluated locally, then uploaded as DTCG)
particles token-studio push --file ./src/theme.ts

# Same for plain JS
particles token-studio push --file ./src/theme.js

# Override the default tier assigned to tokens that don't declare one
particles token-studio push --file ./tokens/globals.json --tier semantic

The format is detected from the file extension. A --dry-run prints a summary of what would change without modifying any data in the project:

terminal
Dry run (no changes applied):
  + 12 tokens added
  ~ 3 tokens updated
  - 1 token removed
ExtensionParsed as
.jsonAuto-detected: DTCG/W3C, Tokens Studio, Style Dictionary, or Particles JSON
.cssCSS custom properties — :root { --color-brand: #3b82f6; }
.scssSCSS variables — $color-brand: #3b82f6;
.jsJS theme object exported as export const theme = { … }
.tsTypeScript theme object — as const and export type lines are stripped before evaluation
i

JS and TS files are evaluated locally in a sandboxed context before upload — no code runs on the Particles platform. Composition tokens represented as nested objects in JS/TS become individual flat leaf tokens after import. Use DTCG JSON if you need to preserve composition token structure.

token-studio branch create

Create a new branch forked from an existing one. Tokens from the source branch are copied into the new branch so you can experiment without touching the original. Defaults to forking from main.

i

Requires the branch:create permission — granted to Admin role or Designers with elevated branch permissions on the project.

terminal
# Fork from main (default)
particles token-studio branch create rebrand-2025

# Fork from a specific branch
particles token-studio branch create rebrand-sub --from rebrand-2025

token-studio scan

Scan your local source files for usages of governed tokens — CSS custom properties and dotted token paths across css, scss, ts/tsx, js/jsx, html, vue, and svelte — and post the result to the project's code coverage roll-up. The Studio Overview's Coverage card and the token list's “Uses” column read from the same roll-up, mirroring the Figma plugin's page scan on the code side.

terminal
# Scan the current directory and sync the code-coverage roll-up
particles token-studio scan

# Scope the scan
particles token-studio scan --dir ./src --ext ts,tsx,css

# Preview the counts without posting
particles token-studio scan --dry-run

token-studio find

Search tokens by meaning — "the muted text colour," not just a name substring. Falls back to a plain substring match when semantic search isn't available.

terminal
# Search the branch configured in particles-ui.json
particles token-studio find "muted text colour"

# Search a specific branch, filtered by type and tier, capped to 5 results
particles token-studio find "danger state" --branch rebrand-2025 --type color --tier semantic --limit 5

migrate --scalable

Make Scalable — turn a flat or messy token set into a layered primitive → semantic system. It generates a cleanly-named New set of primitives and semantics from your raw values, then rewrites each matched legacy token into a deprecated alias pointing at its New-set equivalent — never touching the legacy token's rendered value. Your existing token ids, and anything already consuming them, keep resolving to the same value throughout (non-breaking). High-confidence mappings are applied automatically; weaker ones are listed in a report for you to review.

terminal
# Preview + apply on the current branch
particles migrate --scalable

# Target a branch and only auto-accept very confident mappings
particles migrate --scalable --branch rebrand-2025 --min-confidence 0.85
i

Make Scalable is a Business plan capability. The same flow is available as a button in Studio and the Figma plugin, and a single Revert last run restores the pre-migration state — including a--cutover, see below.

migrate --cutover

The deprecated alias layer that migrate --scalable leaves behind is a transition aid, not the end state. --cutover adopts the New set's clean names as canonical: it repoints every surviving reference off the deprecated aliases onto their targets, then deletes the aliases outright, and emits an old→new code-reference report so you can update any hard-coded names in your codebase.

terminal
particles migrate --cutover --branch rebrand-2025
i

Breaking. Cutover deletes the deprecated legacy tokens — anything still referencing them by name (outside Particles, e.g. a bound Figma variable name or a hard-coded string in code) will need to be updated using the emitted report. It is an explicit opt-in and requires the Business plan.

restructure

Value-preserving logical dedup: when multiple tokens share the exact same value, restructure aliases the duplicates to a single canonical primitive, in place — no token is renamed, and no id ever changes. Distinct semantics that happen to share a value are kept as separate tokens, each pointed at the canonical.

terminal
# Dry-run preview (default)
particles restructure --branch rebrand-2025

# Apply the reparent
particles restructure --branch rebrand-2025 --apply

# Undo a previous reparent on the branch
particles restructure --branch rebrand-2025 --revert
i

Restructure is a Business plan capability.

score

Prints the branch's Scalability Score — a read-only measure of dedup coverage, alias structure, naming, and contrast health. Available on every plan; use --min to gate a CI job on it.

terminal
# Print the score for the configured branch
particles score --branch rebrand-2025

# Fail (non-zero exit) if the score drops below 80 — for a CI check
particles score --branch main --min 80

Theme commands#

Manage sub-brand themes and generate per-theme CSS blocks. Themes are project-scoped token overrides applied via a data-theme attribute.

theme list

terminal
particles theme list

theme generate

Generate a [data-theme="name"] { … } CSS block for a single theme.

terminal
# Write to stdout
particles theme generate dark

# Write to a file
particles theme generate dark --out src/themes/dark.css

theme generate-all

Generate one CSS file per theme into a directory.

terminal
particles theme generate-all --out-dir src/themes

Multi-level modules#

For a multi-level product that consumes Foundation / Brand modules, check whether any linked module has a newer release than the one your product is pinned to, and preview the diff before adopting it in the Studio. Both commands are read-only — accepting an update is done in Project → Token modules.

terminal
# List linked modules — pinned release vs latest, and updates available
particles token-studio modules status

# Dry-run diff of a pending module update (added / removed / changed / conflicts)
particles token-studio modules preview <refId>
i

Standalone projects have no modules — modules status simply reports that. The older foundation sync command is deprecated in favour of modules; see Token architecture.

Docs export#

Export your project's design documentation pages to Markdown or HTML for a published release — useful for mirroring docs into a static site or a repo at release time.

terminal
particles docs export --release 1.4.0 --format md --out docs/

See Design documentation for the full command, output shape, and the equivalent webhook export URLs.

CI / GitHub Actions#

A typical CI step that syncs tokens and enforces WCAG AA contrast:

.github/workflows/tokens.yml
- name: Sync design tokens
  run: |
    npx @particlesui/cli auth login  # uses PARTICLES_TOKEN env from CI secrets
    npx @particlesui/cli token-studio sync --version ${{ github.ref_name }} --wcag-level AA
← PREVIOUS
Figma plugin
NEXT →
Connect AI agents