Boolean Build

Add CI to an Expo app in 10 minutes (GitHub Actions)

2026-10-14

If your Expo app has no CI, every PR is a coin flip on whether the next person’s npm install breaks the build. A minimal pipeline — lint, typecheck, and tests — takes ten minutes to add and pays for itself on the first broken PR.

The workflow

.github/workflows/ci.yml:

name: CI
on:
  push:
    branches: [main]
  pull_request:

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
      - run: npm ci
      - run: npm run check

Where npm run check is lint && typecheck && test — the same command you run locally, so there are no surprises.

Make it one command

The trick that keeps CI honest is making local and CI run the same script:

{
  "scripts": {
    "lint": "eslint . --ext .ts,.tsx --max-warnings 0",
    "typecheck": "tsc --noEmit",
    "test": "jest --passWithNoTests",
    "check": "npm run lint && npm run typecheck && npm test"
  }
}

Gotchas

CI is necessary but not sufficient — green lint/tsc/jest can still ship a blank screen or an unproven invariant. That’s what build gates are for; pair the two and your PRs actually mean something.

The CI workflow above (plus the two build gates and local release scripts) ships in the Expo Production Starter.