@ant-design/cli Design Spec#
Overview#
A CLI tool for Code Agents to query antd knowledge and analyze antd usage in projects. Agents invoke it via shell commands and parse structured output (JSON/text/markdown) to assist developers working with antd.
Product Positioning#
- Target user: Code Agents (Claude Code, Codex, Gemini CLI, etc.)
- Invocation: Pure CLI, agents execute via shell
- Data strategy: Bundled — all metadata is included in the CLI package, no remote fetch required
- Output principle: Concise by default,
--detailfor full information
Package Structure#
Single package:
| Package | Purpose |
|---|---|
@ant-design/cli | CLI logic, globally installed, provides antd command |
Bundled Data#
Metadata for all major versions is bundled inside @ant-design/cli:
@ant-design/cli
└── data/
├── versions.json # version index: minor series → snapshot tag (always plain JSON)
├── design-v6.md # design-language doc for v6 (plain markdown, synced from antd's DESIGN.md, served by `antd design.md`)
├── v3.json.gz # latest v3 (final version 3.26.20)
├── v3.26.20.json.gz # snapshot for 3.26.x series
├── v4.json.gz # latest v4 (gzip-compressed in published package)
├── v4.0.9.json.gz # snapshot for 4.0.x series
├── v4.1.5.json.gz # snapshot for 4.1.x series
├── ... # one .json.gz file per minor series
├── v4.24.16.json.gz # snapshot for 4.24.x series
├── v5.json.gz # latest v5
├── v5.0.7.json.gz # snapshot for 5.0.x series
├── ...
├── v6.json.gz # latest v6
└── ...
Note on data format: In the git repository, data files are stored as plain
.jsonfor readable diffs. Duringnpm pack/npm publish, aprepackhook compresses them to.json.gz(gzip level 9), reducing package size from ~136MB to ~25MB. Apostpackhook restores them to.jsonafterward. The loader transparently supports both formats viazlib.gunzipSync()with fallback to plain JSON.
data/versions.json maps each minor series to its representative snapshot tag:
{
"v3": { "3.26": "3.26.20" },
"v4": { "4.0": "4.0.9", "4.1": "4.1.5", "4.24": "4.24.16" },
"v5": { "5.0": "5.0.7", "5.29": "5.29.3" },
"v6": { "6.3": "6.3.2" }
}
Version Snapshot Resolution#
When --version 4.3.5 is requested, loadMetadataForVersion("4.3.5") resolves the best snapshot:
- Exact minor match — look up
"4.3"inversions.json["v4"]→ e.g."4.3.4"→ loaddata/v4.3.4.json - Nearest earlier minor — if
"4.3"is absent, find the largest available minor ≤ 4.3 (e.g."4.1") → load that snapshot - Fallback — load
data/v4.json(latest)
Data Layer Notes#
- On load, component props are deduplicated by name (first entry wins).
- The extraction script handles
\|(escaped pipes in markdown table cells) by replacing them with a placeholder before splitting. This ensures multi-value union types like`primary` \| `dashed` \| `link`are stored correctly as`primary` | `dashed` | `link`instead of being split across wrong columns. - Each version file contains both
enandzhdescriptions, keyed by language semanticdata extracted fromcomponents/*/demo/_semantic.tsxfiles- Data is auto-extracted from antd source via
scripts/extract.ts data/design-v{major}.md(the design-language document served byantd design.md) is not extracted but copied verbatim from antd's repo-rootDESIGN.mdduring sync, since it is hand-curated prose, not derivable data. It is major-grained, soscripts/sync.tschecks out each major's latest tag and copies the file todata/design-v{major}.md(onlydesign-v6.mdexists today; antd has not publishedDESIGN.mdfor v3/v4/v5). If the sourceDESIGN.mdis absent for a major, the existing bundled copy is kept rather than deleted.- A GitHub Actions workflow (
sync.yml) runs daily: for each major version it extracts the latest snapshot and any new minor-series snapshots, then updatesversions.json - Stale snapshots (files not referenced by
versions.json) are cleaned up automatically: when a new patch replaces an old one for the same minor series, the old file is removed inline; a final sweep after sync removes any orphaned snapshot files.versions.jsonis the source of truth — the cleanup scope derives from its contents, not from a hardcoded major-version list - Historical snapshots can be bootstrapped locally via
scripts/bootstrap-snapshots.ts - CLI version aligns with the latest antd version (e.g., antd 6.3.2 → CLI 6.3.2)
- The components schema is consistent across major versions to enable cross-version diffing
Commands#
Knowledge Query#
antd list#
List all components with one-line descriptions and categories.
antd list
antd list --format json
antd list --version 5.0.0
JSON output includes bilingual fields:
[
{"name": "Button", "nameZh": "按钮", "description": "To trigger an operation.", "descriptionZh": "按钮用于开始一个即时操作。", "since": "0.x"}
]
antd info <Component>#
Query component API: props, type definitions, default values.
antd info Button # concise: props name, type, default
antd info Button --detail # full: + description, since, deprecated, FAQ
antd info Button --version 4.24.0 # v4 API
antd info Button --format json # structured output for agents
JSON output (concise):
{
"name": "Splitter",
"description": "Split panels to isolate",
"props": [
{"name": "layout", "type": "`horizontal` | `vertical`", "default": "`horizontal`"},
{"name": "lazy", "type": "`boolean`", "default": "`false`"}
],
"subComponentProps": {
"Splitter.Panel": [
{"name": "defaultSize", "type": "`number | string`", "default": "-"},
{"name": "resizable", "type": "`boolean`", "default": "`true`"}
]
}
}
For components without sub-components (e.g. Button), subComponentProps is omitted.
Most antd components inherit common props (className, style, rootClassName) via Common Props. These are included in the output:
- JSON format: a
commonPropsarray withname,type,default,description,descriptionZhfields. Omitted forConfigProvider(which does not support common props). - Text/markdown format: a separate "Common Props" table after the component-specific props table. Omitted for
ConfigProvider.
Additionally, each component includes an htmlElement field indicating the underlying HTML element (e.g. Button → "button", Input → "input", Card → "div"). This tells consumers which native HTML attributes the component accepts. Omitted for ConfigProvider.
JSON output (--detail):
{
"name": "Button",
"description": "To trigger an operation.",
"whenToUse": "A button means an operation (or a series of operations)...",
"props": [
{
"name": "type",
"type": "primary | default | dashed | text | link",
"default": "default",
"description": "Set button type",
"since": "1.0.0",
"deprecated": false,
"required": false
}
],
"methods": [],
"related": ["Button.Group", "Dropdown.Button"],
"faq": []
}
Text output for components with sub-components shows main props first, then each sub-component section labeled with its full name (e.g. Splitter.Panel).
antd doc <Component>#
Output the full API documentation for a component in markdown format. Useful for agents that need the complete component reference in one call.
antd doc Button # output full markdown docs to stdout
antd doc Button --format json # structured output with name and doc fields
antd doc Button --lang zh # Chinese documentation
JSON output:
{
"name": "Button",
"doc": "## Button\n\nTo trigger an operation.\n\n### When To Use\n..."
}
For text and markdown formats, the raw markdown content is written directly to stdout with no additional decoration. Returns error DOC_NOT_AVAILABLE if documentation is not available for the component (e.g. older CLI versions without doc data).
antd demo <Component> [name]#
Get demo source code. Returns TSX code and its markdown description.
antd demo Button # list all demos for Button
antd demo Button basic # get specific demo code
antd demo Button basic --format json
JSON output:
{
"component": "Button",
"demo": "basic",
"title": "Basic Usage",
"description": "There are `primary` button, `default` button, `dashed` button, `text` button and `link` button in antd.",
"code": "import React from 'react';\nimport { Button } from 'antd';\n\nconst App: React.FC = () => (\n <Button type=\"primary\">Primary Button</Button>\n);\n\nexport default App;"
}
antd token [component]#
Query Design Tokens.
antd token # list all global tokens
antd token Button # component-level tokens with defaults
antd token --version 4.24.0 # v4 has no token system, shows a hint
antd token --version 3.26.0 # v3 uses Less variables, shows a hint
Note: Design Tokens are only available in antd v5+. For v3 and v4, the command returns UNSUPPORTED_VERSION_FEATURE with a suggestion to use Less variables or upgrade to v5.
antd design.md#
Output the antd design-language document (design.md) — a hand-curated description of antd's default light theme, conformant with the google-labs-code/design.md spec. It is the prose-and-token counterpart to antd token: where token lists individual token names, design describes the design language as a whole (color/typography/spacing/radius values plus the principles behind them), so AI design tools (Figma Make, Stitch, etc.) and agents can consume antd's design language directly.
antd design.md # output the design.md for the detected version
antd design.md --version 6.4.0 # design.md for a specific version (resolved by major)
antd design.md --format json # structured output: { "doc": "..." }
The document has two parts:
- YAML front-matter —
colors,typography,rounded,spacing, andcomponents(12 core archetypes with their key states), with concrete values for the default light theme. - Prose sections — Overview, Customization, Colors, Typography, Layout, Elevation & Depth, Shapes, Components, and Do's and Don'ts.
Version resolution: design.md is major-grained — antd rewrites it only across major releases (e.g. v5 → v6), so it is resolved by the target major version (via detectVersion() / --version). A design.md is currently published only for antd v6; requesting a major without one (v3/v4/v5) returns UNSUPPORTED_VERSION_FEATURE with a hint, mirroring how antd token gates v3/v4. It mirrors the canonical DESIGN.md published at https://ant.design/design.md.
antd semantic <Component>#
Query the semantic customization structure of a component — the available classNames and styles keys. Data extracted from components/*/demo/_semantic.tsx files.
antd semantic Table
antd semantic Table --format json
Note: Semantic structure is only available in antd v5+. For v3 and v4, the command returns UNSUPPORTED_VERSION_FEATURE.
Output (text):
Table Semantic Structure:
├── header # Table header area
├── body # Table body area
├── footer # Table footer area
├── cell # Table cell
├── row # Table row
└── wrapper # Outer wrapper
Usage:
<Table classNames={{ header: 'my-header', cell: 'my-cell' }} />
<Table styles={{ header: { background: '#fff' } }} />
Output (json):
{
"name": "Table",
"semanticStructure": [
{"key": "header", "description": "Table header area"},
{"key": "body", "description": "Table body area"},
{"key": "footer", "description": "Table footer area"},
{"key": "cell", "description": "Table cell"},
{"key": "row", "description": "Table row"},
{"key": "wrapper", "description": "Outer wrapper"}
]
}
antd changelog [version]#
Query changelog entries and compare API differences between versions.
antd changelog 6.3.0 # exact version
antd changelog 5.10.0..5.20.0 # version range (inclusive, must be full semver)
antd changelog --format json
antd changelog 4.24.0 5.0.0 # all breaking changes
antd changelog 4.24.0 5.0.0 Select # Select-specific changes
Version range uses <from>..<to> syntax (inclusive on both ends). Both from and to must be full semver (e.g. 5.10.0, not 5.10). Single version returns only that exact version's entries.
API diff mode (changelog <v1> <v2>) output includes: added props, removed props, changed types, renamed props. Cross-major-version diffing (e.g. v4 vs v5) is supported because the components schema is consistent across versions.
Agent Integration#
antd mcp#
Start an MCP (Model Context Protocol) stdio server for IDE agent integration. Exposes antd knowledge-query tools directly to agents in Claude Desktop, Cursor, and other MCP-compatible IDEs.
antd mcp # start with auto-detected version
antd mcp --version 5.20.0 --lang zh # pin version and language at startup
IDE configuration (claude_desktop_config.json):
{
"mcpServers": {
"antd": {
"command": "antd",
"args": ["mcp", "--version", "5.20.0"]
}
}
}
MCP Tools (8):
| Tool | Description |
|---|---|
antd_list | List all components with names, categories, descriptions |
antd_info | Get component props API |
antd_doc | Get full markdown documentation |
antd_demo | Get demo source code |
antd_token | Query Design Tokens |
antd_design_md | Get the design-language document (design.md) |
antd_semantic | Query semantic classNames/styles structure |
antd_changelog | Query changelog or diff API changes between versions |
All tools include MCP annotations: readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false — indicating they are read-only queries against bundled data with no side effects.
MCP Prompts (2):
| Prompt | Description |
|---|---|
antd-expert | General antd expert — tool usage workflow, avoid duplicate calls, query-before-generate |
antd-page-generator | Page generation assistant — fetch all relevant docs before coding |
Global --version and --lang are resolved once at server startup (not per tool call). All tool outputs are JSON. The server uses @modelcontextprotocol/sdk with stdio transport.
Project Analysis#
antd doctor#
Diagnose project-level configuration issues.
antd doctor # run in project root
antd doctor --format json
Checks (in order):
antd-installed— verifies antd is installed in the project; severity: errorreact-compat— antd version compatibility with React versionduplicate-install— detects multiple antd installationsdayjs-duplicate— detects multiple dayjs installations in node_modules; severity: errorcssinjs-duplicate— detects multiple @.../cssinjs installations in node_modules; severity: errorcssinjs-compat— checks @.../cssinjs version satisfies antd peerDependencies range; severity: error (incompatible version) / warning (not installed)icons-compat— checks @.../icons version satisfies antd peerDependencies range; severity: warning (icons are optional)theme-config— theme config validitybabel-plugins— checks for deprecated babel-plugin-import usage with antd v5+cssinjs— CSS-in-JS configuration correctnessecosystem-compat:<shortName>(dynamic, 0–N checks, one per installed@ant-design/*package with peerDependencies) — scansnode_modules/@ant-design/and for each package that declarespeerDependencies, checks that each required dep's installed version satisfies the range. Usessatisfies()with fail-open for unrecognized range formats (e.g. compound>=x <y). Packages with emptypeerDependenciesare skipped. If no@ant-design/*packages are installed, no checks are added. severity: error (version incompatible) / warning (dep not installed). Covers pro-components series, @.../charts, @.../x, @.../icons, @.../cssinjs, and any future@ant-design/*package.
JSON output:
{
"version": "5.20.0",
"checks": [
{"name": "react-compat", "status": "pass", "message": "React 18.2.0 is compatible with antd 5.20.0"},
{"name": "duplicate-install", "status": "fail", "severity": "error", "message": "Found 2 antd installations: 5.20.0, 5.18.0", "suggestion": "Run `npm dedupe` or check your dependency tree"},
{"name": "theme-config", "status": "pass", "message": "Theme config is valid"},
{"name": "cssinjs", "status": "warn", "severity": "warning", "message": "No @ant-design/cssinjs found, SSR style extraction will not work"},
{"name": "dayjs-duplicate", "status": "fail", "severity": "error", "message": "Found 2 dayjs installations", "suggestion": "Run `npm dedupe` to resolve duplicate dayjs versions"},
{"name": "cssinjs-duplicate", "status": "fail", "severity": "error", "message": "Found 2 @ant-design/cssinjs installations", "suggestion": "Run `npm dedupe` to resolve duplicate @ant-design/cssinjs versions"},
{"name": "cssinjs-compat", "status": "fail", "severity": "error", "message": "@ant-design/cssinjs 1.5.0 does not satisfy antd peer requirement >=1.11.0", "suggestion": "Run `npm install @ant-design/cssinjs` (requires >=1.11.0)"},
{"name": "icons-compat", "status": "warn", "severity": "warning", "message": "@ant-design/icons 5.0.0 does not satisfy antd peer requirement >=5.1.0", "suggestion": "Run `npm install @ant-design/icons` (requires >=5.1.0)"}
],
"summary": {"pass": 2, "warn": 2, "fail": 3}
}
antd usage [dir]#
Scan project for antd component/API usage statistics using AST-based analysis (powered by oxc-parser). Detects direct imports (import { Button } from 'antd'), sub-component JSX usage (<Form.Item>, <Table.Column>), and named imports from sub-paths.
antd usage # scan current directory
antd usage ./src # scan specific directory
antd usage --filter Button # filter results to a specific component (short: -f)
antd usage ./src -f Form # combine directory and filter
antd usage --format json
Imports are cross-referenced against the antd metadata for the detected version. Known antd component exports (e.g. Button, Form, Row, Col) appear in components. Non-component antd exports (e.g. message, notification, theme) are reported separately in nonComponents. TypeScript import { type X } syntax is handled — type-only imports are excluded entirely (they are not runtime values and have no component usage to track). Sub-component usage detection uses AST traversal to precisely identify JSX elements (e.g. <Form.Item>, <Table.Column>), automatically excluding method or hook calls (e.g. Form.useForm(), Modal.confirm()).
The scanner skips directories named node_modules, dist, build, .next, .git, and any directory whose name starts with .umi (covers .umi, .umi-production, .umi-test, etc.).
JSON output:
{
"scanned": 42,
"components": [
{"name": "Button", "imports": 18, "files": ["src/pages/home.tsx", "src/components/Header.tsx"]},
{"name": "Form", "imports": 12, "subComponents": {"Form.Item": 35, "Form.List": 3}},
{"name": "Table", "imports": 8, "files": ["src/pages/list.tsx"]}
],
"nonComponents": [
{"name": "message", "imports": 5, "files": ["src/utils/notify.ts"]},
{"name": "theme", "imports": 2, "files": ["src/theme.ts"]}
],
"summary": {"totalComponents": 15, "totalImports": 87}
}
antd lint [file/dir]#
Check antd usage against best practices. Uses AST-based analysis (powered by oxc-parser) on source files for precise detection.
antd lint ./src
antd lint ./src/pages/home.tsx
antd lint --only deprecated # only check deprecated APIs
antd lint --only a11y # only check accessibility
antd lint --only usage # only check usage mistakes
antd lint --only performance # only check performance
antd lint --format json
antd lint --only deprecated --format json --antd-alias @shared-components
Options:
--only <category>— limit checks todeprecated,a11y,usage, orperformance--antd-alias <source>— treat additional package names as aliases ofantd; repeat the flag for multiple wrapper packages.antdremains enabled by default.
JSON output:
{
"issues": [
{
"file": "src/pages/home.tsx",
"line": 12,
"rule": "deprecated",
"severity": "warning",
"message": "Button `ghost` is deprecated (since 5.12.0). Please use `variant` instead"
}
],
"summary": {"total": 1, "deprecated": 1, "a11y": 0, "usage": 0, "performance": 0}
}
Note: This is complementary to ESLint. antd lint focuses on antd-specific knowledge (deprecated APIs per version, prop combination mistakes, antd accessibility) that generic ESLint rules cannot cover.
Rule categories:
- deprecated — Deprecated props (with replacement info from metadata) and deprecated components (
BackTop→FloatButton.BackTop,Button.Group/Input.Group→Space.Compact). Deprecated prop detection uses AST traversal to precisely match props to their owning JSX element, eliminating false positives from sibling components. - a11y — Accessibility: missing
alton Image, missingaria-labelon clickable icons - usage — Prop combination mistakes detected from antd runtime warnings:
- Form.Item
shouldUpdate+dependenciesconflict - Button
ghost+type="link"/type="text"conflict - Checkbox
valueprop outside Checkbox.Group (should bechecked;valueis valid inside Checkbox.Group) - Divider
type="vertical"with children - Select
maxCountwithoutmode="multiple"/mode="tags" - Menu
inlineCollapsedwithoutmode="inline" - QRCode missing
valueprop - Typography.Link
ellipsisas object (only boolean supported) - Typography.Text
ellipsiswithexpandable/rows(not supported) - Radio
optionTypeoutside Radio.Group (only valid inside Radio.Group) - TreeSelect
multiple={false}+treeCheckableconflict
- Form.Item
- performance — Wildcard imports (
import * as) fromantd, configured--antd-aliaspackages, or their subpaths; default imports; disabling virtual scroll on Select. Locale paths (antd/locale/*,antd/es/locale/*,antd/lib/locale/*) are excluded since their default import is the documented pattern and there is no tree-shaking benefit to be gained.
antd migrate <from> <to>#
Version migration guide with optional auto-fix.
antd migrate 3 4 # v3 → v4 migration checklist
antd migrate 4 5 # v4 → v5 migration checklist
antd migrate 5 6 # v5 → v6 migration checklist
antd migrate v4 v5 # v prefix is accepted and normalized
antd migrate 4 5 --component Select # Select-specific migration
antd migrate 4 5 --apply ./src # scan ./src and generate targeted migration prompts
antd migrate --format json
Available migration paths: v3→v4, v4→v5, v5→v6. Multi-version migrations (e.g., v3→v6) are not supported directly — migrate step by step.
Behavior of --apply <dir>:
- Scans the target directory for antd component imports (reuses the
usagescanning logic) - Filters migration steps to only those relevant to the project's actual component usage
- For steps with
searchPattern, matches against file contents to identify affected files - Outputs a targeted, agent-consumable migration prompt with
**Affected files:**listed per step Globalsteps (design token migration, etc.) are always included regardless of component usage- Components not imported in the project are excluded from the output
JSON output (guide mode):
{
"from": "4",
"to": "5",
"steps": [
{
"component": "Select",
"breaking": true,
"description": "Prop `dropdownClassName` renamed to `popupClassName`",
"autoFixable": true,
"codemod": "v5-props-changed-migration"
},
{
"component": "Global",
"breaking": true,
"description": "Less variables removed, use Design Token instead",
"autoFixable": false,
"guide": "See https://ant.design/docs/react/migrate-less-variables"
}
],
"summary": {"total": 42, "autoFixable": 28, "manual": 14}
}
antd env [dir]#
Collect all antd-related environment information for bug reporting or AI-assisted diagnosis.
antd env # text output (copy-paste to GitHub Issues)
antd env --format json # structured JSON for AI consumption
antd env --format markdown # markdown tables
antd env /path/to/project # scan a specific project directory
Collects six categories of information:
- System — OS name and version
- Binaries — Node.js version, package managers (npm/pnpm/yarn/bun), npm registry URL
- Browsers — Installed system browser versions (Chrome, Firefox, Safari, Edge)
- Dependencies — Core antd-related packages (antd, react, react-dom, dayjs, @.../cssinjs, @.../icons)
- Ecosystem — All installed
@ant-design/*andrc-*packages - Build Tools — Frameworks (umi, next, remix, gatsby, taro, etc.), bundlers (webpack, vite, rspack, turbopack, farm), compilers (typescript, babel, swc), CSS tools (less, sass, tailwindcss)
Text output example:
Environment
System:
OS macOS 15.3
Binaries:
Node 20.11.0
pnpm 9.1.0
Registry https://registry.npmmirror.com/
Browsers:
Chrome 131.0.6778.86
Safari 18.3
Dependencies:
antd 5.22.0
react 18.3.1
react-dom 18.3.1
dayjs 1.11.13
@ant-design/cssinjs 1.22.1
@ant-design/icons 5.5.2
Ecosystem:
@ant-design/pro-components 2.8.1
rc-field-form 2.7.0
Build Tools:
umi 4.3.0
typescript 5.6.3
less 4.2.0
JSON output:
{
"system": {"OS": "macOS 15.3"},
"binaries": {"Node": "20.11.0", "pnpm": "9.1.0", "Registry": "https://registry.npmmirror.com/"},
"browsers": {"Chrome": "131.0.6778.86", "Safari": "18.3"},
"dependencies": {"antd": "5.22.0", "react": "18.3.1", "react-dom": "18.3.1", "dayjs": "1.11.13", "@ant-design/cssinjs": "1.22.1", "@ant-design/icons": "5.5.2"},
"ecosystem": {"@ant-design/pro-components": "2.8.1", "rc-field-form": "2.7.0"},
"buildTools": {"umi": "4.3.0", "typescript": "5.6.3", "less": "4.2.0"}
}
Notes:
- Does not run project code — purely static scanning of
node_modulesand system - Uninstalled core deps show as "Not found" (text) or
null(JSON) - Ecosystem/rc-* packages only list installed ones
- Uses
envinfofor cross-platform browser detection
Issue Reporting#
antd bug#
Report a bug to the antd repository (ant-design/ant-design). Auto-collects environment info and generates issue content in the antd-issue-helper format.
antd bug --title "DatePicker crashes with dayjs 2.0"
antd bug --title "..." --steps "1. Click button" --expected "Works" --actual "Crashes"
antd bug --title "..." --reproduction "https://codesandbox.io/s/xxx"
antd bug --title "..." --submit # submit via gh CLI
antd bug --title "..." --format json # structured output for agent preview
Preview mode (default) outputs the assembled issue for review. --submit creates the issue via gh issue create. Returns error GH_NOT_FOUND if gh is not available.
JSON output (preview):
{
"repo": "ant-design/ant-design",
"title": "DatePicker crashes",
"body": "<!-- generated by @ant-design/cli... -->",
"url": "https://github.com/ant-design/ant-design/issues/new?..."
}
antd bug-cli#
Report a bug to the CLI repository (ant-design/ant-design-cli). Same interface as antd bug but with --description instead of --reproduction, targeting the CLI repo.
antd bug-cli --title "antd info crashes on v4 components"
antd bug-cli --title "..." --description "Detailed description..."
antd bug-cli --title "..." --submit
CLI Management#
antd upgrade#
Upgrade the CLI itself to the latest version published on npm.
antd upgrade # upgrade to latest version
antd upgrade --format json # structured JSON output
antd upgrade --lang zh # Chinese output
The command automatically detects which package manager was used to install the CLI by resolving the binary path (which antd on Unix, where antd on Windows) and matching path keywords:
| Path Keyword | Package Manager |
|---|---|
.utoo or utoo/global | utoo |
.cnpm or cnpm/global | cnpm |
yarn/global | yarn |
.pnpm-global or pnpm/global | pnpm |
.bun or bun/install/global | bun |
| Other (path recognized) | npm (fallback) |
If
which/wherefails entirely (binary not in PATH), detection returnsnulland the command exits withPM_NOT_FOUND.
Each package manager uses its own global upgrade command:
| Package Manager | Upgrade Command |
|---|---|
npm | npm install -g @ant-design/cli@latest |
yarn | yarn global add @ant-design/cli@latest |
pnpm | pnpm add -g @ant-design/cli@latest |
bun | bun add -g @ant-design/cli@latest |
cnpm | cnpm install -g @ant-design/cli@latest |
utoo | ut install -g @ant-design/cli@latest |
Flow:
- Fetch the latest version from npm (reuses the existing
fetchLatestVersion()with 3-mirror race: npmjs, npmmirror, unpkg) - Compare with current CLI version (
__CLI_VERSION__) - If already up to date, output and exit 0
- Detect the package manager from the binary path; if detection fails, print error with manual command suggestion and exit 1
- Execute the corresponding upgrade command via
child_process.spawn(120s timeout,stdio: 'inherit'for passthrough,shell: trueon Windows for.cmdcompatibility) - Verify the upgraded version by running
antd --cli-version; if version unchanged, warn and exit 2
Exit codes:
0— success (upgraded or already up to date)1— user error (network error, package manager not detected)2— system error (upgrade command failed, version unchanged after upgrade)
Error codes: NETWORK_ERROR, PM_NOT_FOUND, UPGRADE_FAILED, VERSION_UNCHANGED
Output (already up to date, text):
Already up to date: v6.4.3
Output (already up to date, json):
{"currentVersion":"6.4.3","message":"Already up to date"}
Output (upgrade succeeded, text):
Upgrading @ant-design/cli: v6.4.3 → v6.4.4
Running: npm install -g @ant-design/cli@latest
... (passthrough package manager output) ...
Successfully upgraded to v6.4.4
Output (upgrade succeeded, json):
{"previousVersion":"6.4.3","newVersion":"6.4.4","packageManager":"npm"}
Output (upgrade succeeded, markdown):
## Upgrade
| Field | Value |
|---|---|
| Previous Version | 6.4.3 |
| New Version | 6.4.4 |
| Package Manager | npm |
Global Flags#
| Flag | Description | Default |
|---|---|---|
--format json|text|markdown | Output format. json includes all data with no decoration. | text |
--version <v> | Target antd version (full semver, e.g. 5.20.0) | auto-detect from project |
--lang en|zh | Output language | en |
--detail | Full information output (more fields in response) | false |
Note: --quiet removed. --format json already provides clean structured output for agents. --format text is for human-readable output and always includes formatting.
Version Detection#
Priority order:
--versionflag (highest)- Installed version in
node_modules/antd/package.json - Declared version in project
package.jsondependencies - Fallback version — the latest bundled major, resolved dynamically from the highest
data/v{N}.jsonsnapshot'sversionfield (e.g.6.4.3), so it tracks "latest" as new majors are synced instead of going stale
Resolution: The CLI maps the resolved version to a major version data directory (e.g. 5.20.0 → v5/), then filters props/tokens by since and deprecated fields against the exact version. If the resolved version does not exist as a published antd version (e.g. 5.999.0), the CLI warns and uses the latest known version within that major.
Error Handling#
All commands return a standard error shape when they fail:
{
"error": true,
"code": "COMPONENT_NOT_FOUND",
"message": "Component 'Btn' not found",
"suggestion": "Did you mean 'Button'?"
}
Exit codes:
0— success1— user error (invalid args, component not found)2— system error (file read failure, data corruption)
Common error codes: COMPONENT_NOT_FOUND, VERSION_NOT_FOUND, NO_PROJECT_DETECTED, UNSUPPORTED_VERSION_FEATURE (e.g. tokens for v3/v4), NETWORK_ERROR, PM_NOT_FOUND, UPGRADE_FAILED, VERSION_UNCHANGED.
Technical Architecture#
┌─────────────┐ ┌──────────────┐ ┌──────────────────┐
│ CLI Layer │────>│ Data Layer │────>│ Data Sources │
│ │ │ │ │ │
│ Commands │ │ Version │ │ Bundled data │
│ Flag parse │ │ routing │ │ data/v4,v5,v6 │
│ Output fmt │ │ Filtering │ │ (JSON files) │
└─────────────┘ └──────────────┘ └──────────────────┘
Tech Stack#
- Language: TypeScript + Node.js
- CLI framework:
commander - Minimum Node version: 20+
- Package name:
@ant-design/cli - Global command:
antd
Data Extraction Pipeline#
The extraction script scripts/extract.ts runs against an antd source checkout to produce bundled JSON files:
npx tsx scripts/extract.ts --antd-dir ~/Projects/ant-design --output data/v6.json
Extraction sources:
| Data | Source | Method |
|---|---|---|
| Component list, category, description | components/*/index.{en-US,zh-CN}.md frontmatter | gray-matter YAML parsing |
| When To Use | index.{en-US,zh-CN}.md ## When To Use section | Markdown section extraction |
| Props | index.{en-US,zh-CN}.md ## API tables | Markdown table parsing |
| Demos | components/*/demo/*.tsx + *.md | File read + bilingual md parsing |
| Tokens | components/version/token-meta.json | Direct JSON read |
| Semantic | components/*/demo/_semantic.tsx | Regex extraction of locales + semantics |
| Changelog | CHANGELOG.{en-US,zh-CN}.md | Markdown heading/emoji parsing |
| FAQ | index.{en-US,zh-CN}.md ## FAQ section | Markdown section extraction |
Extractors are organized as scripts/extractors/*.ts modules (components, props, demos, tokens, semantic, changelog, faq).
Update Check#
After each command completes, the CLI silently checks whether a newer version is available on npm and prints a notice to stderr if so. The check runs at most once per 24 hours; results are cached locally.
Cache file: ~/.config/antd-cli/update-check.json
{ "lastChecked": 1710000000000, "latestVersion": "0.2.0" }
Notice format (stderr only):
╭────────────────────────────────────────╮
│ Update available: 0.1.1 → 0.2.0 │
│ Run: antd upgrade │
│ Or: npm i -g @ant-design/cli │
╰────────────────────────────────────────╯
Behavior details:
- Skipped when
CI=1orNO_UPDATE_CHECK=1is set - Bug-reporting suggestions in SKILL.md and MCP prompts are skipped when
ANTD_NO_AUTO_REPORT=1is set - Uses
registry.npmjs.orgwith a 3 s timeout; failures are silent - Output goes to stderr, so
--format jsonstdout is never polluted - No new production dependencies — uses only built-in Node modules (
node:https,node:fs,node:os,node:path)
Self-Upgrade#
The antd upgrade command upgrades the CLI to the latest version. It detects the package manager from the binary path and executes the matching global install command. Key modules:
| Module | Purpose |
|---|---|
src/commands/upgrade.ts | Command registration + main flow |
src/utils/detect-pm.ts | Package manager detection from binary path |
src/utils/update-check.ts | fetchLatestVersion() reused for version check |
The command reuses the existing fetchLatestVersion() (3-mirror race + 24h cache) for checking the latest version, and compare() from src/data/version.ts for semver comparison.
Automated Data Sync#
GitHub Actions workflow .github/workflows/sync.yml runs daily:
- For each major version (v4, v5, v6), find the latest antd release tag via
git ls-remote - Checkout antd source at that tag
- Run
scripts/extract.tsto generate new data - If data changed, commit and push
- Align CLI version with the latest antd version and publish to npm
The CLI version is kept in sync with antd — e.g., when antd publishes v6.3.2, the CLI is also published as v6.3.2.
Output Examples#
antd info Table --format json (concise)#
{
"name": "Table",
"description": "A table displays rows of data.",
"props": [
{"name": "columns", "type": "ColumnsType<T>", "default": "-"},
{"name": "dataSource", "type": "T[]", "default": "-"},
{"name": "loading", "type": "boolean | SpinProps", "default": "false"},
{"name": "pagination", "type": "false | TablePaginationConfig", "default": "-"},
{"name": "rowKey", "type": "string | (record) => string", "default": "key"},
{"name": "rowSelection", "type": "object", "default": "-"},
{"name": "scroll", "type": "{x, y}", "default": "-"},
{"name": "size", "type": "large | middle | small", "default": "large"}
]
}
antd changelog 4.24.0 5.0.0 Select --format json#
{
"component": "Select",
"from": "4.24.0",
"to": "5.0.0",
"added": [
{"name": "popupClassName", "type": "string"}
],
"removed": [
{"name": "dropdownClassName", "replacement": "popupClassName"}
],
"changed": [
{"name": "dropdownMatchSelectWidth", "renamed": "popupMatchSelectWidth"}
]
}