skip to content

In an Expo project, what is the difference between npx expo install --check and --fix, and how would you use each in CI?

level: middleimportance: should knowfreq 38%

answer

  1. validate versus correct
  2. --check prompts locally
  3. non-zero exit when not interactive
  4. --fix always installs
  5. expo.install.exclude for deliberate pins

basics

~10 s

npx expo install --check compares installed packages with the SDK's expected versions and reports mismatches, prompting to fix when interactive and exiting non-zero in CI. --fix installs the expected versions unconditionally.

solid answer

~40 s

Both compare the project's dependencies with the versions the installed Expo SDK expects. `--check` validates: it lists mismatches and, in an interactive terminal, asks whether to fix them; in CI it cannot prompt, so it exits with a non-zero code, which makes it a gate that keeps the lockfile unchanged. `--fix` corrects: it installs the expected versions wherever needed, in any environment, and is what you run after bumping `expo` during an upgrade. Both accept package names to limit the scope, such as `npx expo install react-native --check`. A package deliberately held at another version goes into `expo.install.exclude` in `package.json`, which removes it from `npx expo install`, `npx expo-doctor` and `npx expo start` checks. So CI runs `--check` and fails the build; a developer runs `--fix` and commits the result.

code

bash · 6 lines
bash
# CI: validate only; exits non-zero on any mismatch and changes nothing
npx expo install --check

# Local: correct every mismatch, then review and commit the diff
npx expo install --fix
git diff package.json

go deeper

for a junior

Know that --check reports packages that do not match the SDK and --fix installs the expected versions.

for a middle

Explain the interactive prompt versus the non-zero exit in CI, scoping by package name, and install.exclude.

for a senior

Gate CI on --check, keep --fix a reviewed local step, and trace drift back to its source such as bots or plain npm installs.

for a principal

Make dependency alignment an enforced policy with recorded exceptions, so SDK upgrades start from a known-clean state.

## Two flags, two jobs Every Expo SDK has a **known-versions map**: the versions of Expo packages and popular third-party libraries that were tested with that SDK's React Native. `npx expo install` uses it to install; the `--check` and `--fix` flags use it to **audit** what is already installed. | | `npx expo install --check` | `npx expo install --fix` | |---|---|---| | Purpose | validate | correct | | Interactive terminal | lists mismatches, asks whether to fix | installs expected versions | | CI / non-interactive | exits non-zero on mismatches, changes nothing | installs expected versions | | Changes `package.json` and lockfile | only if you accept the prompt | yes, when something is wrong | | Typical use | a CI gate, a quick local audit | after upgrading `expo`, repairing drift | When everything matches, both report that dependencies are up to date. ## Scoping and output - Pass package names to limit the audit: `npx expo install react-native expo-sms --check`. - `npx expo install expo-camera` and `npx expo install expo-camera --fix` serve the same purpose for a single package; `--fix` without names is the whole-project version. - `--json`, used with `--check`, prints the mismatches as JSON for tooling and exits non-zero when anything is outdated. ## Deliberate exceptions Sometimes you need a version the SDK does not map, for example a library release with a fix you depend on. Add it to `expo.install.exclude` in `package.json`: ```json { "expo": { "install": { "exclude": ["react-native-reanimated"] } } } ``` Excluded packages are skipped by `npx expo install`'s checks, by `npx expo-doctor`, and by the dependency check `npx expo start` runs at startup. The CLI prints which packages it skipped, so the exception stays visible. ## Using them in CI A sound setup for a pet-adoption app's pipeline: 1. **Install from the lockfile** exactly as committed. 2. **Run `npx expo install --check`.** In CI it cannot prompt, so any mismatch exits non-zero and fails the job without changing files. 3. **Never run `--fix` in CI** as a silent repair: it would build something different from what was reviewed, and the corrected lockfile would be lost with the job. 4. **Fix locally.** A developer runs `npx expo install --fix`, reviews the diff, and commits it. This keeps the rule simple: CI detects drift; people correct it. ## Where drift comes from - A developer ran `npm install some-native-lib` instead of `npx expo install`. - A dependency bot bumped a library past the version the SDK maps. - `expo` was upgraded but its companion packages were not. - A merge resolved `package.json` conflicts by picking the higher versions. Each of these produces a project that may still build, but on combinations nobody tested. ## The start-up check `npx expo start` performs the same validation when it launches, unless you are offline or `EXPO_NO_DEPENDENCY_VALIDATION` is set, and warns that listed packages "should be updated for best compatibility" with the installed `expo` version. That warning is the same signal `--check` gives, just earlier and easier to ignore. ## A worked example A pet-adoption app's CI starts failing on a Monday. The log from `npx expo install --check` lists `react-native-screens` at a version newer than SDK 57 maps. The history shows a dependency bot bumped it over the weekend. The fix is not to relax the gate: a developer runs `npx expo install --fix`, which moves the package back to the mapped range, reviews the diff and commits it. The team then configures the bot to leave SDK-mapped packages alone, because those move with SDK upgrades, not on their own. If the newer version had been needed for a real bug, the right move would have been an explicit version plus an `expo.install.exclude` entry, not a silent bump. ## Mistakes to avoid - Treating `--check` in CI as advisory; its non-zero exit is the whole point. - Excluding a package to silence a warning without writing down why. - Running `--fix` and committing without reading the diff, which can hide a major version jump.

  • Why not just run npx expo install --fix in CI and carry on?
    It would build a dependency set nobody reviewed, and the corrected `package.json` and lockfile would vanish with the job, so the drift stays in the repository. Running `--check` makes CI fail loudly; a developer then runs `--fix` locally, reads the diff and commits it.
  • A library must stay on a version the SDK does not map; how do you stop the checks failing?
    List it in `expo.install.exclude` in `package.json`. `npx expo install --check`, `npx expo-doctor` and the start-up validation then skip it, and the CLI notes the exclusion, so the exception is visible and deliberate rather than a warning everyone learns to ignore.

saying these in an interview costs you the question

  • --check and --fix both change package.json by default
  • --check in CI only prints warnings and exits successfully
  • Running --fix in CI is a safe way to keep builds green
  • install.exclude only affects npx expo install, not doctor or start
  • --fix checks versions but never installs anything