Skip to content

mfe-forge doctor ​

Diagnose common environment and topology problems.

Synopsis ​

text
mfe-forge doctor [--json]

Description ​

doctor runs a fixed set of read-only checks against the workspace in the current directory and reports each one as pass, warn, or fail. It never modifies files. The exit code is 2 if any check fails, and 0 otherwise (warnings do not fail the run).

Options ​

FlagTypeDefaultDescription
--jsonbooleanfalsePrint the structured report instead of human output.
-h, --helpbooleanShow help.

Checks ​

Checks run in this order. Their id values are stable and appear in JSON output.

node-version ​

StatusConditionMessage
passNode.js major version is 20 or newerNode v22.x.x
failNode.js older than 20Node <version> is too old

Fix: install Node.js 20 or newer.

lockfile ​

Checks that the workspace root contains a lockfile for defaults.packageManager.

Package managerAccepted lockfiles
bunbun.lock, bun.lockb
pnpmpnpm-lock.yaml
npmpackage-lock.json
StatusMessage
passLock file present for <pm>
failNo lock file found for <pm>

Fix: run <pm> install. If the configured package manager is wrong, change it with mfe-forge config --set defaults.packageManager --value pnpm.

ports ​

Detects apps that share a dev-server port. Ports are read from the first port: <n> in each app's vite.config.ts; an app with no literal port is treated as port 3000.

StatusMessage
passNo port conflicts
failPort conflicts: <a> and <b> both use port <n>; ...

Fix: change server.port and preview.port in one of the vite.config.ts files, and the --port value in that app's dev/preview scripts. Then run mfe-forge sync so hosts pick up the new URL.

hosts ​

Runs only when at least one app exists. Every scope that contains apps must also contain apps/<scope>/host.

StatusMessage
passAll scopes have hosts
failScopes without a host: <scope>, ...

Fix: mfe-forge generate host <scope>/host.

workspaces ​

StatusConditionMessage
passRoot package.json has workspaces or bun.workspacesWorkspaces configured
failRoot package.json has neitherRoot package.json missing workspaces configuration
warnNo root package.jsonNo root package.json found

Fix: add "workspaces": ["apps/*/*", "packages/*"] to the root package.json. Only the field's presence is checked, not whether its globs match your apps.

Output ​

text
🔍 Running diagnostics...

  ✔ Node v22.11.0
  ✖ No lock file found for pnpm
      Run `pnpm install`
  ✔ No port conflicts
  ✔ All scopes have hosts
  ✔ Workspaces configured

4 passed, 0 warnings, 1 failed

JSON report (DoctorReport):

json
{
  "ok": false,
  "summary": { "pass": 4, "warn": 0, "fail": 1 },
  "checks": [
    { "id": "node-version", "status": "pass", "message": "Node v22.11.0" },
    {
      "id": "lockfile",
      "status": "fail",
      "message": "No lock file found for pnpm",
      "hint": "Run `pnpm install`"
    }
  ]
}

hint is present only on non-passing checks. The same report is available programmatically:

ts
import { loadConfig, runDoctor } from 'mfe-forge'

const root = process.cwd()
const report = await runDoctor({
  rootDir: root,
  config: loadConfig(root),
  appsDir: `${root}/apps`,
  packagesDir: `${root}/packages`,
  scopes: [],
})

runDoctor(context, nodeVersion?) takes a ProjectContext and returns a Promise<DoctorReport>.

TIP

Attach mfe-forge doctor --json output to bug reports.

Failure modes ​

SituationExit code
All checks pass or warn0
Any check fails2
Configuration invalid3 (no checks run)

Released under the MIT License.