Dosu LogoDosu Logo
Ask
Join our Discord
Ant DesignPublic
Ant Design
DocumentsAnt Design
2026-03-24-doctor-ecosystem-peerdeps-design
2026-03-24-doctor-ecosystem-peerdeps-design
Type
External
Status
Published
Created
Jun 12, 2026
Updated
Jun 12, 2026
Source
docs/superpowers/specs/2026-03-24-doctor-ecosystem-peerdeps-design.md

Design: antd doctor — Ecosystem peerDeps Compatibility Check#

Date: 2026-03-24
Status: Approved

Summary#

Extend antd doctor to dynamically scan all installed @ant-design/* packages and verify that each package's peerDependencies are satisfied by the currently installed environment. This covers both:

  1. Ecosystem → antd: does the installed antd version satisfy what pro-components / charts / etc. require?
  2. Ecosystem → other deps: does the installed react / cssinjs / icons version satisfy each ecosystem package's requirements?

Background#

The current doctor command already checks:

  • cssinjs-compat: from antd's peerDeps perspective — does installed cssinjs satisfy antd's requirement?
  • icons-compat: same for icons

These are kept as-is. The new check is complementary: it goes in the other direction, asking "does the installed environment satisfy what each ecosystem package needs?"

Design#

Data Collection (DoctorContext)#

Add to buildContext():

  • Scan node_modules/@ant-design/ (i.e. readdirSync(join(cwd, 'node_modules', '@ant-design'))) to discover all installed scoped packages. Note: antd itself lives at node_modules/antd/, NOT under @ant-design/, so it will never appear in this scan.
  • For each entry, read node_modules/@ant-design/<entry>/package.json to extract: version, peerDependencies, peerDependenciesMeta
  • Add ecosystemPackages: EcosystemPackage[] field to DoctorContext
  • Add getInstalledVersion(cwd, pkgName): string | null helper function that reads node_modules/<pkgName>/package.json. This is a standalone helper and is self-contained within the new check; it does not replace existing ctx.cssinjsPkg / ctx.iconsPkg fields used by existing checks.
interface EcosystemPackage {
  name: string; // e.g. "@ant-design/pro-components"
  shortName: string; // e.g. "pro-components"
  version: string;
  peerDependencies: Record<string, string>;
  peerDependenciesMeta: Record<string, { optional?: boolean }>;
}

New Check Function#

checkEcosystemPeerDeps(ctx: DoctorContext): CheckResult[]

Algorithm per installed ecosystem package:

  1. Skip packages with no peerDependencies field (no check emitted)
  2. For each entry in peerDependencies:
    • Look up installed version of that dep via getInstalledVersion()
    • If not installed: warn (regardless of optional/required — follows the same pattern as checkCssinjsCompat)
    • If installed but version doesn't satisfy range (via satisfies()): fail with severity=error
    • Range format limitation: satisfies() does not support compound ranges like ">=5.0.0 <6.0.0" or ">=4 || >=5". For any range that satisfies() cannot parse, it fails-open (returns true, i.e. treated as compatible). This is intentional v1 scope: false negatives are preferred over false positives for unknown range formats.
  3. Aggregate violations for the package into one CheckResult:
    • Any version-incompatible dep → status: 'fail', severity: 'error'
    • Only missing deps (not installed) → status: 'warn', severity: 'warning'
    • No issues → status: 'pass'
  4. name format: ecosystem-compat:<shortName> (e.g. ecosystem-compat:pro-components)

message/suggestion split#

For a failing check:

  • message: "@ant-design/pro-components 2.7.0 peerDep issues: antd requires >=5.16.0 (installed: 5.10.0)" — summarizes the violation(s) in the message
  • suggestion: "Run \npm install antd@latest`"` — the actionable fix

For multiple violations, the message concatenates them with ; .

Integration#

In registerDoctorCommand action:

const checks: CheckResult[] = [
  // existing checks...
  ...checkEcosystemPeerDeps(ctx),
];

The function returns CheckResult[] (empty if no ecosystem packages are found).

Skip Logic#

Packages to skip during ecosystem scan:

  • antd itself
  • Packages with no peerDependencies field (e.g. icon SVG assets, color utilities)

Output (text format)#

antd Doctor

  ✓ [antd-installed] antd 5.10.0 is installed
  ✓ [react-compat] React 18.2.0 is compatible with antd 5.10.0
  ...
  ✗ [ecosystem-compat:pro-components] @ant-design/pro-components 2.7.0 peerDep issues:
    → antd requires >=5.16.0 (installed: 5.10.0) — run `npm install antd@latest`
  ✓ [ecosystem-compat:icons] @ant-design/icons 5.3.0 satisfies all peerDependencies
  ✓ [ecosystem-compat:cssinjs] @ant-design/cssinjs 1.11.0 satisfies all peerDependencies

Summary: 5 passed, 0 warnings, 1 failed

Output (JSON format, appended to existing checks array)#

{
  "name": "ecosystem-compat:pro-components",
  "status": "fail",
  "severity": "error",
  "message": "@ant-design/pro-components 2.7.0 peerDep issues: antd requires >=5.16.0 (installed: 5.10.0)",
  "suggestion": "Run `npm install antd@latest` to satisfy @ant-design/pro-components peerDependencies"
}

Files Changed#

  • src/commands/doctor.ts — main changes
  • spec.md — update doctor checks list
  • src/__tests__/cli.test.ts — add ecosystem peerDep test cases

Testing#

  • Mock node_modules/@ant-design/pro-components/package.json with peerDeps
  • Test: incompatible antd version → status: 'fail', severity: 'error'
  • Test: missing optional peerDep (via peerDependenciesMeta) → status: 'warn'
  • Test: missing required (non-optional) peerDep → status: 'warn' (follows checkCssinjsCompat precedent: "not installed" = warn, not fail)
  • Test: all satisfied → status: 'pass'
  • Test: no ecosystem packages installed → no new checks added
  • Test: package with no peerDependencies → skipped (no check emitted)
  • Test: compound range (>=5.0.0 <6.0.0) that satisfies() cannot parse → treated as compatible (fail-open)

Non-Goals#

  • Network requests to npm registry (all checks are local file reads only)
  • Checking non-@ant-design/* packages (e.g., antd-mobile)
  • Modifying existing cssinjs-compat / icons-compat checks (kept as-is)
Documents
Masonry Server-Side Rendering
2026-03-17-doctor-enhancements
2026-03-17-doctor-enhancements-design
2026-03-20-bug-fixes-round-2
2026-03-23-bug-report-commands
2026-03-23-bug-report-commands-design
2026-03-24-antd-mcp-server-design
2026-03-24-doctor-ecosystem-peerdeps
2026-03-24-doctor-ecosystem-peerdeps-design
2026-03-26-env-command
2026-03-26-env-command-design
2026-04-02-antd-v3-support-design
2026-04-02-antd-v3-support-plan
2026-04-17-opt-out-auto-report-design
2026-05-26-upgrade-command-design
AGENTS
CHANGELOG
CHANGELOG
CHANGELOG
CHANGELOG.zh-CN
CLAUDE
HISTORY
HISTORY
README
README
README
README
README
README
README
README
README
README
README.zh-CN
README.zh-CN
RFC-createStaticStyles
SKILL
antd-based-components.en-US
antd-based-components.zh-CN
antd-override.en-US
antd-override.zh-CN
babel-plugin.en-US
babel-plugin.zh-CN
bug_report
changelog.en-US
changelog.zh-CN
clay.en-US
clay.zh-CN
color-panel
compare.en-US
compare.zh-CN
components-usage.en-US
components-usage.zh-CN
controlled
create-instance.en-US
create-instance.zh-CN
create-static-styles.en-US
create-static-styles.zh-CN
create-styles.en-US
create-styles.en-US
create-styles.zh-CN
create-styles.zh-CN
create-stylish.en-US
create-stylish.zh-CN
css-in-js-intro.en-US
css-in-js-intro.zh-CN
cssinjs-compiler-difference.en-US
cssinjs-compiler-difference.zh-CN
custom-theme.en-US
custom-theme.zh-CN
custom-token-types.en-US
custom-token-types.zh-CN
design-v6
feature_request
fix-switch-theme-fouc.en-US
fix-switch-theme-fouc.zh-CN
genStyleUtils
global-styles.en-US
global-styles.zh-CN
index
index
index
index
index
index
index.en-US
index.en-US
index.zh-CN
index.zh-CN
index.zh-CN
intro
intro
introModal
introModal
mac-select.en-US
mac-select.zh-CN
migrate-less-application.en-US
migrate-less-application.zh-CN
migrate-less-codemod.en-US
migrate-less-codemod.zh-CN
migrate-less-component.en-US
migrate-less-component.zh-CN
mirgration-less-global-style.en-US
mirgration-less-global-style.zh-CN
motivationHelp
motivationHelp
nest-element-style.en-US
nest-element-style.zh-CN
overview
performance-comparsion.en-US
performance-comparsion.zh-CN
performance.en-US
performance.zh-CN
previewer-token-panel
proposalHelp
proposalHelp
question
reproHelp
reproHelp
reproModal
reproModal
setup-styled.en-US
setup-styled.zh-CN
spec
ssr.en-US
ssr.zh-CN
static-message.en-US
static-message.zh-CN
stepsHelp
stepsHelp
strategy.en-US
strategy.zh-CN
style-provider.en-US
style-provider.zh-CN
styled.en-US
styled.en-US
styled.zh-CN
styled.zh-CN
stylish.en-US
stylish.zh-CN
switch-theme.en-US
switch-theme.zh-CN
theme
theme-provider.en-US
theme-provider.zh-CN
use-responsive.en-US
use-responsive.zh-CN
use-theme-mode.en-US
use-theme-mode.zh-CN
use-theme.en-US
use-theme.zh-CN