Environment variables are global values that are defined in your system. Without these variables, your operating system wouldn't know what to do when you execute a command like expo start. Under the hood, it uses the PATH variable to fetch a list of directories to search for the expo executable.
Because they are defined globally, these variables are useful to change the behavior of code without changing the code itself. Just like your system behaving "differently" when adding directories to the PATH variable, you can implement these in your Expo app as well. For example, you can enable or disable certain features when building a testing version of your app, or you can switch to a different API endpoint when building for production.
The app manifest .env
If you have installed the expo-constants module in your managed workflow project, you can access the app manifest's properties. One of these properties is the .env property, a property that is only available when running expo start. As the name suggests, it contains some of your system-defined environment variables. For security reasons, only the variables that starts with REACT_NATIVE_ or EXPO_ are available.
While the .env property can be useful during development, this property is not available when running expo publish or expo build. It should not be used for feature flagging or other app-specific configuration because of this.
Using app manifest .extra
In the app manifest, there is also a .extra property. Unlike .env, this property is included when you publish your project with expo publish or expo build. The contents of the .extra property are taken from your app manifest. By default, this does not add any environment variables, but we can make that happen with the dynamic app manifest configuration.
You can also use manifest.extra.enableComments directly in your if statement, but that makes it a bit harder to test or override.
Using Babel to "replace" variables
In the bare workflow, you don't have access to the manifest via the expo-constants module. You can still use environment variables using another method, a Babel plugin. This approach replaces all references to process.env.VARNAME with the variable contents, and works in both Bare and Managed Workflows.
Keep in mind that all environment variables are parsed as a string. If you use booleans like true or false, you have to check using their string equivalent.
Using a dotenv file
Over time your app grows, and more configuration is added. When this happens, it could get harder to find the correct environment variables to start or build your app. Luckily, there is a concept called "dotenv" that can help when this happens.
A dotenv file is a file with all environment variables, and their value, within your project. You can load these dotenv files in Node with a library called dotenv.
Below you can see the dynamic manifest using this dotenv library. It imports the /config module to automatically load the .env and merge it with process.env. You can also use it without merging it to process.env, read more about that here.
The official transform-inline-environment-variables plugin does not load the .env file. If you want to use these files with Babel, you can use unofficial plugins like babel-plugin-inline-dotenv. This plugin will load your .env when Babel is building your app.
Never store sensitive secrets in your environment variables. The reason behind this is that your code is run on the client side, and thus including your environment variables in the code itself. You can read more about this topic here.