0004. Environments and configuration
- Status: Accepted
- Date: 2026-10-10
- Questions: B4, B5
Context
Section titled “Context”Most templates bake one .env into the JS bundle. Real apps need dev, staging and prod builds installed side by side, each with its own bundle id, name, icon, backend and Firebase project.
Decision
Section titled “Decision”- Three environments (B4): dev, staging, prod.
- Android: a
environmentflavor dimension withdev,staging,prod. dev and staging useapplicationIdSuffix(.dev,.staging), and each flavor sets its ownapp_nameand icon insrc/<flavor>/res. - iOS: one target with configurations
Debug-Dev,Release-Dev,Debug-Staging,Release-Staging,Debug-ProdandRelease-Prod, each backed byios/Config/<Env>.xcconfig(bundle id suffix, display name, app icon set). One shared scheme per environment. - Config (B5):
react-native-configreads.env.dev,.env.stagingand.env.prodon both the native and JS sides. In JS,src/shared/config/env.tsis the only file that reads it, and it parses the values with Zod so a missing or malformed value fails at startup with a clear message. .env.*files hold public configuration only. Secrets never go in the app.
Consequences
Section titled “Consequences”- iOS configuration names must be passed to
run-ios(--mode Debug-Dev). Thepackage.jsonscripts hide this. - Adding an environment touches Gradle, xcconfig, the scheme list and
.env.*.docs/environments.mdlists the steps.
Alternatives considered
Section titled “Alternatives considered”- JS-only env file: cannot change bundle ids, names or Firebase projects per environment.
Addendum (2026-10-10): demo builds
Section titled “Addendum (2026-10-10): demo builds”pnpm build:android:demo builds the dev flavor in release mode from index.demo.js, which adds the in-app
mock backend, so the app can be tried on a phone before a backend exists. Gradle refuses -PdemoBuild for
the staging and prod flavors, and CI checks that release bundles from index.js contain no mock code.