Ant Design CLI: How Offline Metadata Snapshots Power Agent-Driven Development
Hook
Your code agent hallucinates deprecated Ant Design props because it was trained on documentation from 2021. This CLI fixes that by shipping version-specific API snapshots directly to your terminal—and to Claude.
Context
Ant Design is one of the most popular React UI libraries, with over 90,000 GitHub stars and millions of weekly downloads. But its rapid release cycle creates a documentation problem: every minor version introduces new props, deprecates old ones, and shifts design tokens. Developers constantly tab-switch to the docs site to verify which props exist in their specific version. Code agents have it worse—they hallucinate APIs from their training cutoff date, suggest deprecated patterns, and can't distinguish between v4 and v5 syntax.
The traditional solution is IDE extensions or ESLint plugins, but both require manual maintenance. When Ant Design ships version 5.25.0 with new Table props, extension authors must update JSON configs and push new releases. By the time developers install the update, v5.26.0 is already out. Ant Design CLI takes a different approach: it precompiles API metadata for 55+ minor versions (spanning v3 through v6) as static JSON files and ships them as package assets. The CLI auto-detects your project's antd version by walking node_modules, then serves exact API data from the bundled snapshot. No network calls, no stale docs, no version guessing. And crucially, it exposes this functionality through the Model Context Protocol (MCP), turning the CLI into a knowledge source for AI agents working in your codebase.
Technical Insight
The architecture centers on three components: metadata snapshots, version resolution, and command dispatch. The snapshots live in dist/metadata/ as JSON files keyed by version (e.g., 5.24.0.json). Each file contains every component, prop, design token, and migration note for that specific release—about 2MB of structured data per version. This is compiled once at CLI build time from Ant Design's TypeScript definitions and changelogs, not fetched at runtime. When you run antd info Button, the CLI first resolves which version you're using.
Version detection is surprisingly tricky. The CLI tries three strategies in order: (1) parse your package.json to extract the antd semver range and resolve it against shipped snapshots, (2) walk node_modules/antd/package.json to find the installed version (handling pnpm symlinks and Yarn PnP), (3) default to 5.24.0 if both fail. Once it knows the version, it loads the corresponding snapshot and filters to the requested component. Here's what the data structure looks like for a single prop:
{
"component": "Button",
"prop": "type",
"type": "'primary' | 'default' | 'dashed' | 'link' | 'text'",
"default": "'default'",
"description": "Can be set to primary, default, dashed, link, or text",
"deprecated": false,
"version": "5.24.0"
}
The deprecation linting system is where offline snapshots shine. Instead of hardcoding rules like "Button.ghost is deprecated in v5," the CLI diffs metadata between versions at runtime. When you run antd lint --version 4.24.0 --target 5.0.0, it loads both snapshots, compares every prop/component, and flags removals or type changes. This means the lint rules are always version-accurate without manual updates:
$ antd lint --target 5.0.0
Deprecated usage found:
• Form.hideRequiredMark → removed in 5.0.0, use requiredMark="optional"
• Button.danger with type="link" → breaking change in 5.0.0
• PageHeader component → removed, use Layout + Typography
The MCP server implementation is the most forward-looking piece. MCP (Model Context Protocol) is Anthropic's standard for exposing tools to AI agents. The CLI includes a server subcommand that runs a stdio-based JSON-RPC server. When Claude Desktop or Cursor connects, the CLI registers tools like query_component, list_deprecations, and get_migration_guide. Here's a simplified example of how an agent queries component info:
// Agent sends JSON-RPC request over stdin
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "query_component",
"arguments": { "component": "Table", "version": "5.24.0" }
}
}
// CLI responds with structured metadata
{
"jsonrpc": "2.0",
"result": {
"component": "Table",
"props": [/* 40+ prop definitions */],
"tokens": { "colorPrimary": "#1677ff" },
"examples": "import { Table } from 'antd';\n..."
}
}
This turns the CLI into a zero-install IDE extension. Instead of building separate plugins for VS Code, JetBrains, and Vim, the CLI exposes one MCP interface that any agent-enabled editor can consume. Cursor can ask "what props does Table accept in my project's antd version" without the developer typing a command.
The migration tooling generates actionable checklists rather than running AST transforms. When you run antd migrate --from 4.24.0 --to 5.0.0, you get markdown output with regex patterns and manual steps:
## Breaking Changes (12 items)
### 1. Form.hideRequiredMark removed
- **Search pattern:** `hideRequiredMark`
- **Replace with:** `requiredMark="optional"`
- **Auto-fixable:** Yes
- **Files affected:** src/components/UserForm.tsx (2 instances)
### 2. PageHeader component removed
- **Migration:** Use `<Layout><Typography.Title>` instead
- **Auto-fixable:** No (requires structural changes)
- **Docs:** https://ant.design/components/page-header#migration
The --apply flag doesn't execute these changes—it formats them as prompts for LLM agents to interpret. This is a philosophical choice: the CLI assumes an agent (or human) will validate and apply changes rather than running blind codemods that might break custom wrapper components.
Typo correction uses Levenshtein distance with domain-specific weighting. If you type antd info Tabel, the CLI calculates edit distance to all known components, boosts matches with the same first letter (since components are PascalCase), and suggests corrections. This is implemented in about 50 lines of TypeScript and handles common typos better than fuzzy finders that don't understand naming conventions.
Gotcha
The precompiled snapshot model has a fundamental staleness problem. If Ant Design ships version 5.25.0 today and adds a new Table.sticky prop, you won't see it in the CLI until the maintainers rebuild snapshots and publish a new CLI version. This usually happens within a week, but if you're on the bleeding edge or using release candidates, the CLI is blind to new APIs. There's no fallback to fetch live data from npm or the docs site—it's offline-only, which is both a feature and a limitation.
The migration system generates checklists, not code. If you're expecting a jscodeshift-based codemod that rewrites your imports and prop usage automatically, you'll be disappointed. Running antd migrate --apply just adds an --output prompt flag that formats the checklist for LLM consumption—it doesn't touch your files. You still need to manually search-and-replace (or feed the output to an agent that can edit code). The official @ant-design/codemod-v5 package does run AST transforms, but it's a separate tool that only covers the v4→v5 upgrade. This CLI is broader (covers v3-v6) but shallower (no AST analysis).
The doctor command for detecting duplicate antd installations shells out to npm ls, yarn list, or pnpm list and parses the text output with regex. This breaks if package managers change their output format, and it can't detect phantom dependencies (packages in node_modules that aren't in package.json) or workspace hoisting edge cases where multiple antd versions are intentionally present. It's a heuristic check, not a dependency graph analysis.
Finally, the linting rules are read-only. You can't extend them with custom checks for your team's internal antd wrapper components or organizational conventions. If you've built a <MyButton> that wraps <Button> and want to enforce props usage, you'll need to fork the CLI or use ESLint plugins instead. The CLI is opinionated about what it checks (official Ant Design APIs only) and doesn't expose a plugin system.
Verdict
Use if: You're building with Ant Design and using AI agents (Claude, Cursor, GitHub Copilot) that need version-accurate API context without hallucinating deprecated props, or you want instant offline component documentation in your terminal faster than opening a browser. The MCP integration makes this essential for teams adopting agentic workflows—your agents will stop suggesting Form.hideRequiredMark in v5 projects. Also valuable for airgapped environments or slow network connections where docs site lookups are painful. Skip if: You need actual AST-based codemods that rewrite code automatically (use @ant-design/codemod-v5 or jscodeshift instead), you're not using Ant Design at all, or you're on a bleeding-edge antd version and need same-day API updates (the CLI's snapshot model lags by days). Also skip if you want deep static analysis integrated into your ESLint workflow—this is a CLI tool, not a linter plugin, so it won't block commits or show inline editor warnings without MCP agent integration.