Hash every env var you read
A variable missing from env serves builds made with the old value.
From turborepo, environment/RULE.md and gotchas.md.
Staging URL in a prod build
Build, switch API_URL to production, build again.
Not declaredBad
dist/app.js
not built"build": { "outputs": ["dist/**"] }In envGood
dist/app.js
not built"env": ["API_URL"]Turbo never reads .env
Change a value in apps/web/.env.production.
Default inputsBad
"env": ["DATABASE_URL"].env in inputsGood
"inputs": ["$TURBO_DEFAULT$", ".env*"]{
"tasks": {
"build": {
"dependsOn": ["^build"],
"env": ["API_URL", "DATABASE_URL", "NEXT_PUBLIC_*", "!NEXT_PUBLIC_ANALYTICS_ID"],
"inputs": ["$TURBO_DEFAULT$", ".env", ".env.local", ".env.production", ".env.production.local"],
"outputs": [".next/**", "!.next/cache/**", "!.next/dev/**"]
}
}
}
Why it matters, pros and cons
Why it matters
Values in env are part of the hash. Your framework loads .env files, and they are gitignored, so only inputs makes turbo hash them.
Pros
- Each value gets its own cache entry.
- Switching back is an instant hit.
- Wildcards and
!keep long lists short.
Cons
- Framework prefixes like
NEXT_PUBLIC_*are inferred already. - Vars set inside a script are invisible to turbo.
- A long
envlist is fine, not a smell.