EAS Build Uploads Entire Monorepo Instead of Mobile Folder

EAS Build Uploads Entire Project Instead of Just Mobile Folder Despite .easignore

Summary

EAS Build uploaded the entire monorepo (client + server folders) instead of only the mobile project, despite the presence of a .easignore file. The developer had placed .easignore inside the mobile subfolder, expecting it to filter out the server directory. This resulted in unnecessary upload times, larger build artifacts, and potential exposure of server-side code to the build environment.

Root Cause

The root cause is a misunderstanding of where .easignore must be placed and how EAS Build determines the project root.

  • .easignore must exist at the project root, not in subdirectories like mobile/
  • EAS Build operates from the directory where package.json is located (the project root)
  • The .easignore file in mobile/ was never read because EAS Build looked for it at the root level
  • Without a root-level .easignore, EAS Build defaults to uploading everything except what .gitignore already excludes

Why This Happens in Real Systems

This issue commonly occurs in monorepo setups where developers assume subdirectory configuration files will be respected.

  • Monorepo structure confusion: Developers create separate folders for mobile, backend, and web, then expect each to have its own build configuration
  • Tool documentation gaps: EAS documentation emphasizes .gitignore behavior but .easignore placement is not prominently highlighted
  • Assumption of local context: The developer believed that running eas build from within the mobile/ folder would use that folder’s configuration
  • No explicit error: EAS Build does not warn when it cannot find .easignore, making the misconfiguration silent

Real-World Impact

  • Increased upload times: Uploading unnecessary files adds minutes to every build
  • Larger build artifacts: Server code bundled unnecessarily increases storage and CI costs
  • Security concerns: Backend code present in build context could accidentally be exposed in logs or artifacts
  • Team confusion: Other developers may not realize why builds are larger than expected
  • CI/CD pipeline bloat: Longer build queues and resource consumption

Example or Code (if necessary and relevant)

Incorrect setup (what the developer had):

my-project/
├── mobile/
│   ├── .easignore  ← EAS IGNORES THIS FILE
│   ├── App.tsx
│   └── package.json
├── server/
│   └── ...
└── client/
    └── ...

Correct setup (what should be used):

my-project/
├── .easignore  ← CORRECT LOCATION
├── mobile/
│   ├── App.tsx
│   └── package.json
├── server/
│   └── ...
└── client/
    └── ...

Example .easignore content:

server/
client/
*.md
.env.local
node_modules/.cache

How Senior Engineers Fix It

  • Place .easignore at the project root alongside package.json
  • Use absolute or root-relative paths in .easignore (e.g., server/ not ./server/)
  • Verify with eas build:inspect before running full builds to see exactly what will be uploaded
  • Consider using workspace configuration if the monorepo uses Yarn workspaces or npm workspaces
  • Run npx expo export --platform android locally to test what gets bundled
  • Check .gitignore interactions: EAS respects .gitignore first, then applies .easignore rules

Why Juniors Miss It

  • Assuming subdirectory config works: Many tools allow per-folder config (like .eslintrc in subdirs), so juniors expect the same pattern
  • Not reading the “placement” requirement: Documentation often mentions what a file does but not where it must live
  • No visible error: The build succeeds, just with extra files, so there’s no immediate feedback that something is wrong
  • Focusing on the wrong flag: Juniors often look for CLI flags like --directory instead of understanding the config file placement
  • Copy-pasting from tutorials: Many tutorials show single-project setups where root placement is implicit and never explained

Leave a Comment