expo-ci-doctor logoexpo-ci-doctor

✨ What's New

expo-ci-doctor is now 100% free and open source.

All commands below are fully available with no account, no key, and no subscription required.

doctorFull project health audit with categorized checks and a readiness score
doctor --fixAutomatically apply detected fixes interactively
logs <file>Deep-analyze a CI build log, identify root causes, and suggest fixes
explain-errorPaste an error snippet and get a plain-language explanation
fixStandalone interactive fixer for auto-fixable issues
badgeGenerate a README health badge for your project
ci-templateGenerate CI workflow files for GitHub, GitLab, CircleCI, or Bitbucket
watchWatch config files and re-run checks automatically on save
reportExport a full Markdown report to expo-ci-report.md
snapshot + diffSnapshot project state and diff against a baseline
upgradeSimulate an Expo SDK upgrade and preview breaking changes

Getting Started

expo-ci-doctor statically analyzes your Expo and React Native project to predict CI and EAS build failures before they happen. It reads your package.json, app.json, eas.json, native configs, and CI workflows — entirely locally, with zero telemetry.

It requires Node.js 18+ and works in any directory containing a valid Expo or React Native project.

Installation

Run without installing (recommended for CI):

$ npx expo-ci-doctor@latest doctor

Install globally for repeated local use:

$ npm install -g expo-ci-doctor

Verify installation:

$ expo-ci-doctor --version

Requirements: Node.js 18+. No API key. No account. No internet connection required during analysis.

Quick Start (5 minutes)

From zero to a passing CI pipeline in four steps:

1

Run a full health audit

$ npx expo-ci-doctor@latest doctor

Categorizes your project across 8 check areas and produces a 0–100 health score.

2

Fix detected issues

$ npx expo-ci-doctor@latest fix

Interactively walks you through auto-fixable issues (npm install / expo install commands).

3

Verify with a quick scan

$ npx expo-ci-doctor@latest check

Fast scan of all rules with detailed per-file output and a readiness score box.

4

Add to CI

$ npx expo-ci-doctor@latest ci-template

Generates a workflow file for GitHub Actions, GitLab CI, CircleCI, or Bitbucket Pipelines.

Commands Reference

All commands support global flags: --ci, --json, --json-full, --format md, --severity <error|warn|info>.

Configuration (.expo-ci-doctorrc)

Place a .expo-ci-doctorrc or .expo-ci-doctor.json file in your project root to customize behavior.

.expo-ci-doctorrc
{
  "rules": {
    "DEP_CARET_PIN": "off",
    "DEP_RN_PEER": "warn"
  },
  "failThreshold": 70,
  "ignoreRules": [],
  "monorepoDetection": true
}
rulesOverride individual rule levels: "error" | "warn" | "off"
failThresholdScore below this number causes exit code 1. Default: 50.
ignoreRulesArray of rule IDs to skip entirely.
monorepoDetectionEnable or disable monorepo-aware scanning. Default: true.

CI Integration

Recommended setup: run preflight or ci before your EAS build step to gate on errors. Use doctor for a fuller audit.

.github/workflows/expo-ci.yml
name: Expo CI

on: [push, pull_request]

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20

      - name: Install dependencies
        run: npm ci

      # Fast gate: fail immediately on blocking errors
      - name: Preflight check
        run: npx expo-ci-doctor@latest preflight

      # Full audit (optional — shows score + all warnings)
      - name: Full doctor audit
        run: npx expo-ci-doctor@latest doctor

      # Emit GitHub PR annotations
      - name: CI annotations
        run: npx expo-ci-doctor@latest ci

      - name: EAS Build
        run: npx eas-cli build --platform all

GitLab CI

Run ci-template to auto-generate .gitlab-ci.yml

npx expo-ci-doctor@latest preflight

CircleCI

Run ci-template to auto-generate .circleci/config.yml

npx expo-ci-doctor@latest preflight

Bitbucket

Run ci-template to auto-generate bitbucket-pipelines.yml

npx expo-ci-doctor@latest preflight

Examples & Recipes

Before pushing — run a full audit

$ npx expo-ci-doctor@latest doctor

# → see health score + issues. If score is below 80, fix before pushing.

Debugging an EAS build failure

# Download the log from your EAS dashboard or capture locally

$ eas build --platform android 2>&1 | tee build.log

$ npx expo-ci-doctor@latest logs build.log

# → root cause identified with fix suggestion

Generating a CI workflow file

$ npx expo-ci-doctor@latest ci-template

# → pick your CI provider, file is written to disk

Creating a PR report

$ npx expo-ci-doctor@latest report

# → creates expo-ci-report.md — attach to PR or commit to repo

Adding a health badge to your README

$ npx expo-ci-doctor@latest badge --markdown

# → outputs the markdown snippet, paste it into your README

Watching config changes locally

$ npx expo-ci-doctor@latest watch

# → leave running in a second terminal. Checks re-run on every save.

Before an Expo SDK upgrade

$ npx expo-ci-doctor@latest snapshot

# → save pre-upgrade state

$ npx expo-ci-doctor@latest upgrade expo@52

# → preview breaking changes

# ... do the upgrade ...

$ npx expo-ci-doctor@latest diff expo-doctor-snapshot.json

# → confirm what changed

Troubleshooting

Error: No package.json found

Run expo-ci-doctor from the root of your Expo project (the directory containing package.json and app.json). In a monorepo, run from the individual app workspace directory.

My build passes but doctor reports a WARN

Warnings are non-fatal heuristic suggestions. If you're confident your configuration is correct, add the rule ID to ignoreRules in your .expo-ci-doctorrc file.

explain-error opens an empty editor and exits

Set your $EDITOR environment variable: export EDITOR=nano (or code, vim, etc.). Without it, some environments default to a non-interactive editor.

logs command shows 0 patterns matched

The pattern database covers common Expo/EAS/RN failures. Project-specific errors (custom native modules, unusual Gradle configs) may not be matched. Try running with --noise low to filter out noise and focus on high-confidence patterns.

FAQ