Handling Multiple Environments
Publish Stallion bundles for staging, production, and other environments using environment-specific .env files.
Handling Multiple Environments
Most React Native apps ship to more than one environment — typically a staging build that points at staging APIs and a production build that points at production APIs. When you adopt Stallion OTA, the same bundle you publish must respect that separation: a bundle built for staging should never reach production users, and vice versa.
This guide explains how to publish environment-specific bundles when your app reads its configuration from .env files via react-native-dotenv, which picks the active env file based on NODE_ENV (or a custom APP_ENV for non-standard environments like staging).
How Environment Values End Up in a Bundle
Environment values are inlined into the JavaScript bundle at Babel transform time. Internally, stallion publish-bundle invokes react-native bundle, which runs your Babel pipeline — so whichever env file is active during that step is the one whose values get baked into the bundle.
The implication is simple: you choose the target environment by setting the right env var on the publish command itself.
Important:
Because env values are inlined at build time, a single published bundle is bound to one environment. Publish a separate bundle for each environment and upload each to its own bucket.
Publishing a Bundle Per Environment
Prefix the publish-bundle command with the env var that selects the target environment. react-native-dotenv resolves the active env file from NODE_ENV (e.g. NODE_ENV=production loads .env.production), with APP_ENV available as an override for environments that don't fit the development / production split — APP_ENV cannot be development or production itself, since those names are reserved for NODE_ENV.
Staging
APP_ENV=staging npx stallion publish-bundle \
--upload-path=<org>/<project>/<staging-bucket> \
--platform=android \
--release-note="staging test build"
Production
NODE_ENV=production npx stallion publish-bundle \
--upload-path=<org>/<project>/<production-bucket> \
--platform=android \
--release-note="V1.x.x production"
The same pattern applies for iOS — swap --platform=android for --platform=ios.
Tip:
Use a dedicated bucket per platform per environment (for example, staging-android, staging-ios, production-android, production-ios). This keeps releases isolated in the Stallion Console and makes promotion mistakes far less likely.
For the full list of publish-bundle flags, see the Publish Bundle API Reference.
Reset the Metro Cache Between Environments
This is the single most common pitfall. Metro caches transformed modules aggressively, and those cached transforms include the inlined env values from the previous run. If you switch env files without clearing the cache, Metro may reuse the previous environment's transforms — and the published bundle will silently contain the wrong values.
Always clear the Metro cache before publishing for a different environment:
# macOS / Linux
rm -rf "$TMPDIR/metro-"* node_modules/.cache/metro
# Windows (PowerShell)
Remove-Item -Recurse -Force "$env:TEMP\metro-*", "node_modules\.cache\metro" -ErrorAction SilentlyContinue
Note:
If a published bundle is reporting values from the wrong environment, a stale Metro cache is almost always the cause. Clear it and republish.
Verifying the Published Bundle
After publishing, install the matching environment build of your app on a device and confirm that:
- The OTA update is delivered to that build.
- Runtime values from the env file (API base URLs, feature flags, keys, etc.) resolve to the expected environment.
- Network requests are hitting the expected backend.
Do this for every environment you publish to before promoting the release.
Common Pitfalls
- Skipping the cache reset. Stale Metro transforms are the leading cause of "wrong environment in production" bugs.
- Sharing one bucket across environments. It works, but it makes mistakes during promotion much more likely. Prefer one bucket per environment.
- Forgetting iOS. Each platform produces its own bundle; publish for both
--platform=androidand--platform=iosper environment. - Mismatched app build. A bundle published for staging will only behave correctly inside the staging build of the app. Always verify against the matching native build.