Notes

Environment variables in Expo using Release Channels

Edit on GitHub

Expo
3 minutes
  • You can reference the release channel with Constants.manifest.releaseChannel. It’s part of expo-constants
  • Default values for releaseChannel are:
    • undefined in dev mode
    • default in production
  • Constants.manifest.releaseChannel does NOT exist in dev mode, it’ll return undefined. It does exist, however when you explicitly publish / build with it.
  • If you don’t specify a release channel, it’ll publish to a channel called default

Here’s what i use, it uses indexOf to accomodate for different variations in channel names and __DEV__ to set default environment when releaseChannel is undefined

 1import Constants from 'expo-constants'
 2
 3const ENV = {
 4  develop: {
 5    API_URL: 'https://api-dev.myapp.net/v1',
 6  },
 7  staging: {
 8    API_URL: 'https://api-stg.myapp.net/v1',
 9  },
10  production: {
11    API_URL: 'https://api.myapp.net/v1',
12  },
13}
14
15const getEnvVars = (env = Constants.manifest.releaseChannel) => {
16  // Default values for `releaseChannel` are `undefined` in dev mode and `default` in production
17  if (__DEV__) {
18    return ENV.develop
19  }
20
21  // using `indexOf` will let you pick up dev, develop, development, dev-v1, dev-v2, dev-v3, and so on..
22  // Returns `-1` if the value is not found.
23  if (env.indexOf('dev') !== -1) return ENV.develop
24  if (env.indexOf('staging') !== -1) return ENV.staging
25  if (env.indexOf('prod') !== -1) return ENV.production
26  return ENV.develop // If you do not specify a channel, you will publish to the `default` channel.
27}
28
29export default getEnvVars()

here’s how you’d use it in another file

1import ENV from '../../environment'
2
3const activityUrl = `${ENV.API_URL}/activity`

here’s how indexOf works: if the env string contains the string dev, it’ll return the index of where it occurs. if env starts with dev, it’ll return 0. if it returned -1, then the substring wasn’t found inside the env string

 1let env1 = 'development'
 2console.info(env1.indexOf('dev')) // 0
 3
 4let env2 = 'dev'
 5console.info(env2.indexOf('dev')) // 0
 6
 7let env3 = 'develop'
 8console.info(env3.indexOf('dev')) // 0
 9
10let env4 = 'dev-v1'
11console.info(env4.indexOf('dev')) // 0
12
13let env5 = 'develop-v3'
14console.info(env5.indexOf('dev')) // 0
15
16let env6 = 'prod-v3'
17console.info(env6.indexOf('dev')) // -1
18
19let env7 = 'development'
20console.info(env7.indexOf('ment')) // 7

Here’s Peter Piekarczyk’s snippet:

 1import { Constants } from 'expo'
 2
 3const ENV = {
 4  dev: {
 5    apiUrl: 'http://localhost:1337/api',
 6  },
 7  staging: {
 8    apiUrl: 'https://staging.orchard.ai/api',
 9  },
10  prod: {
11    apiUrl: 'https://orchard.ai/api',
12  },
13}
14
15function getEnvVars(env = '') {
16  if (env === null || env === undefined || env === '') return ENV.dev
17  if (env.indexOf('dev') !== -1) return ENV.dev
18  if (env.indexOf('staging') !== -1) return ENV.staging
19  if (env.indexOf('prod') !== -1) return ENV.prod
20}
21
22export default getEnvVars(Constants.manifest.releaseChannel)

and here’s Alex’s snippet:

 1import Constants from 'expo-constants'
 2
 3const getEnvVars = (env = Constants.manifest.releaseChannel) => {
 4  // What is __DEV__ ?
 5  // This variable is set to true when react-native is running in Dev mode.
 6  // __DEV__ is true when run locally, but false when published.
 7  if (__DEV__) {
 8    return ENV.dev
 9  } else if (env === 'staging') {
10    return ENV.staging
11  } else if (env === 'prod') {
12    return ENV.prod
13  }
14}
15
16export default getEnvVars
1// Import getEnvVars() from environment.js
2import getEnvVars from '../environment'
3const { apiUrl } = getEnvVars()