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.
.easignoremust exist at the project root, not in subdirectories likemobile/- EAS Build operates from the directory where
package.jsonis located (the project root) - The
.easignorefile inmobile/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.gitignorealready 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
.gitignorebehavior but.easignoreplacement is not prominently highlighted - Assumption of local context: The developer believed that running
eas buildfrom within themobile/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
.easignoreat the project root alongsidepackage.json - Use absolute or root-relative paths in
.easignore(e.g.,server/not./server/) - Verify with
eas build:inspectbefore 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 androidlocally to test what gets bundled - Check
.gitignoreinteractions: EAS respects.gitignorefirst, then applies.easignorerules
Why Juniors Miss It
- Assuming subdirectory config works: Many tools allow per-folder config (like
.eslintrcin 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
--directoryinstead of understanding the config file placement - Copy-pasting from tutorials: Many tutorials show single-project setups where root placement is implicit and never explained