skip to content

What does eas build --local do in an Expo project, and how does it differ from a build on EAS's cloud servers?

level: juniorimportance: should knowfreq 35%

answer

  1. same pipeline, your machine
  2. debugging cloud build failures
  3. one platform, no caching
  4. you install the toolchain
  5. still logs in to EAS

basics

~20 s

eas build --local runs the same build process EAS runs in the cloud, but on your own macOS or Linux machine. It is for debugging cloud failures or keeping builds in-house; it needs your own toolchain and skips caching.

solid answer

~40 s

`eas build --local` runs the EAS Build process through the `eas-cli-local-build-plugin` on your machine instead of on EAS servers, and writes the artifact to the current directory or to `--output`. Its main use is **reproducing a cloud build failure** with the same steps; it also suits policies that forbid third-party build machines, since EAS is contacted only to check the project and, with managed credentials, to download them. The differences: one `--platform` at a time (no `all`), the image and tool-version fields in `eas.json` (`node`, `yarn`, `fastlane`, `cocoapods`, `ndk`, `image`) are ignored, caching is off, Secret-visibility EAS environment variables must be set locally, and you install Node, the Android SDK and NDK, and CocoaPods and fastlane for iOS yourself. It still needs `eas login` or `EXPO_TOKEN`.

code

bash · 4 lines
bash
# reproduce a failing cloud Android build and keep the working directory
EAS_LOCAL_BUILD_SKIP_CLEANUP=1 \
EAS_LOCAL_BUILD_WORKINGDIR=$HOME/eas-debug \
  eas build --platform android --profile production --local --output ./app.aab

go deeper

for a junior

Recall that --local runs the EAS build process on your own machine and produces the app file locally.

for a middle

Explain the differences from cloud builds: one platform, ignored tool versions, no caching, local secrets and a toolchain you install.

for a senior

Use it as a debugging instrument: keep the working directory, read the Xcode logs, and change one environment variable at a time to find a cloud-only failure.

for a principal

Assess local or self-hosted EAS builds against cloud builds for policy, cost and reproducibility, including who maintains the build machines.

## What --local means `eas build` normally uploads your project to **EAS Build** servers, which install dependencies, run prebuild if needed, compile and sign the app. `eas build --local` runs that same sequence on **your machine**. EAS CLI delegates the job to a package called `eas-cli-local-build-plugin`, and the resulting `.aab`, `.apk` or `.ipa` is copied to the current directory, or to the path given with `--output`, a flag that is accepted only for local builds. EAS CLI's help text still labels `--local` as experimental. It is **not** the same as `npx expo run:android` or `npx expo run:ios`, which compile a development build with the native tools directly. `--local` reproduces the EAS pipeline, including the build profile, credentials handling and lifecycle hooks. ## Why teams use it - **Debugging.** When a cloud build fails and the logs are not enough, running the identical steps locally lets you inspect the working directory. `EAS_LOCAL_BUILD_SKIP_CLEANUP=1` keeps the directory, `EAS_LOCAL_BUILD_WORKINGDIR` chooses it, and for iOS its `logs` subdirectory holds the Xcode logs. - **Policy.** Organisations that may not send source code to a third-party build service can still use EAS's pipeline. EAS is contacted only to confirm that the project exists and, if you use managed credentials, to download them. ## What differs from a cloud build | Aspect | Cloud build | `--local` | |---|---|---| | Platforms per command | `android`, `ios` or `all` | one platform only | | Tool versions (`node`, `yarn`, `fastlane`, `cocoapods`, `ndk`, `image`) | honoured from `eas.json` | ignored; your installed versions are used | | Build `cache` | supported | not supported | | Secret-visibility EAS environment variables | available | not available; export them locally | | Toolchain | provided by the build image | you install Node, package manager, Android SDK and NDK, CocoaPods and fastlane for iOS | | Host OS | EAS machines | macOS or Linux; Windows is unsupported, WSL untested | An iOS local build also needs a Mac with Xcode, because that is where iOS apps are compiled. ## What stays the same 1. **Authentication.** You still need `eas login`, or `EXPO_TOKEN` in automation. 2. **Build profiles.** `--profile` selects the same `eas.json` profile, with its environment and credentials source. 3. **Lifecycle hooks.** `package.json` hooks such as `eas-build-pre-install` run too; a script can tell the runs apart with `EAS_BUILD_RUNNER`, which is `local-build-plugin` locally and `eas-build` in the cloud. 4. **Versioning.** `autoIncrement` and the app version source behave as configured, because the CLI resolves the version before handing off the job. ## Useful environment variables - `EAS_LOCAL_BUILD_SKIP_CLEANUP=1` — keep the temporary working directory after the build. - `EAS_LOCAL_BUILD_WORKINGDIR` — choose where that directory is created; by default it is under the system temp directory. - `EAS_LOCAL_BUILD_ARTIFACTS_DIR` — where artifacts are copied, instead of the current directory. ## When not to use it `--local` is the wrong tool in a few common situations: - **Everyday development.** For running the app on a simulator or device while coding, `npx expo run:android` or `npx expo run:ios`, or a development build, is faster and gives you the dev server. - **A shared release pipeline.** A local build depends on whatever tools are installed on that machine, so two developers can produce different binaries from the same commit. Releases are more reproducible from cloud builds or a dedicated, managed machine. - **Building both platforms at once.** Each run handles one platform, so a script has to call it twice. ## A reasonable mental model Think of `--local` as moving the build **worker**, not changing the build **recipe**. Differences in output between a local and a cloud build therefore usually come from the environment you now own — a different Node or CocoaPods version, a missing secret, no cache — which is exactly what makes it a good debugging tool: change one variable at a time until the local run fails like the cloud one, or succeeds where it failed.

  • Why can a local EAS build succeed while the same profile fails in the cloud?
    Locally, the image and tool-version fields in `eas.json` are ignored and your own Node, CocoaPods or NDK are used; caching is off; Secret-visibility variables come from your shell. Any of those can differ from the cloud machine, so compare versions and variables first.
  • When would you use npx expo run:ios instead of eas build --local?
    For day-to-day development builds on a simulator or device: `run:ios` compiles with Xcode directly and starts the dev server. `eas build --local` is for reproducing the EAS pipeline itself, with its profile, credentials and hooks, typically to debug a cloud failure.

saying these in an interview costs you the question

  • eas build --local works without an Expo login
  • eas build --local --platform all builds both apps in one run
  • The node and image fields in eas.json apply to local builds
  • eas build --local is just another name for expo run:android
  • Local builds restore the same cache as cloud builds