What Are React Environment Variables?
React environment variables are predefined key-value pairs used to configure and manage various settings in a React application without hardcoding them directly into the source code. These variables allow developers to adjust configurations for different environments, such as development, testing, and production, without modifying the codebase.
Environment variables in React are particularly useful for storing sensitive information like API keys, database connection strings, and other configuration details that should not be exposed in the source code. They help in maintaining clean, secure, and easily maintainable code.
In this article:
The Importance of Environment Variables in React
React environment variables simplify configuration and improve security.
Application Configuration
Environment variables provide a scalable way to manage different settings across multiple deployment environments, such as development, testing, and production. By changing environment variables, a developer can influence application behavior without altering code.
This capability is especially useful in scenarios where multiple variants of an application must be deployed with distinct configurations. For example, different database connections or third-party service credentials can be configured through these variables.
Security
Using environment variables improves application security by segregating sensitive data from source code. When credentials or API keys are stored as environment variables, they aren’t exposed in the codebase or version control repositories. This reduces the risk of sensitive data being accessed or leaked in unauthorized environments.
Environment variables also allow for the dynamic management of credentials, making it easier to rotate secrets regularly without changing the application’s code. This practice is crucial for maintaining security standards in the deployment pipeline.
Note: Environment variables are not secure on their own, because they are stored in plaintext and visible to anyone with access to your environment. However, they can be made more secure in combination with encryption, secret management, or configuration management tools.
How Environment Variables Work in React
In React, environment variables are defined as key-value pairs that must be set in the shell before the server or application starts. These variables follow a specific format to ensure they are recognized by the React engine.
For example, you can define an environment variable in your shell like this:
REACT_APP_YOUR_VARIABLE_NAME_HERE=somevalue
React requires all custom environment variables to have the prefix REACT_APP_
. Variables without this prefix are ignored during the bundling process. This precaution helps prevent the accidental exposure of private keys or sensitive information that may have similar names.
React loads these variables into process.env
, a global object provided by Node.js at runtime. This object represents the state of the environment in which your app is running. Since environment variables in this context have global scope, they can be accessed directly in the code.
For example, if you have an environment variable named REACT_APP_MY_API_KEY
, you can access its value in your React code like this:
const apiKey = process.env.REACT_APP_MY_API_KEY;
This ensures that sensitive information, such as API keys, can be included in your application without hardcoding them directly into the codebase.
Note: Environment variable names ,ust adhere to a standard naming convention. They may only contain uppercase letters, digits, and underscores. They cannot begin with a digit.
Tips From Expert
In my experience, here are tips that can help you better manage React environment variables:
-
Use
.env.local
for sensitive environment variables during development Store sensitive environment variables, such as API keys, in a.env.local
file that is git-ignored. This ensures that these keys aren’t accidentally pushed to a public repository but are available locally for development. -
Standardize fallback values for robustness Always provide fallback values when accessing environment variables to avoid runtime crashes if a variable is missing. For example:
const apiUrl = process.env.REACT_APP_API_URL || 'https://default.api.com';
This prevents issues caused by missing or misconfigured variables in different environments. -
Separate secrets from client-side configurations Avoid storing sensitive information like API keys in environment variables that will be exposed on the client side. For critical secrets, use a backend service or API gateway to manage and secure access, passing them securely from the server side.
-
Utilize environment-specific
.env
files Maintain separate.env
files for different environments, such as.env.development
,.env.staging
, and.env.production
. React will automatically load the appropriate file based on theNODE_ENV
value, ensuring environment-specific configurations are applied seamlessly. -
Validate environment variables in build pipelines Add validation checks in your CI/CD pipeline to ensure required environment variables are set correctly before deploying. Use libraries like
env-cmd
or custom scripts to enforce this, avoiding deployment issues due to missing configurations.
Quick Tutorial: Setting Environment Variables in React
To set environment variables in a React application, you typically use .env
files or define them directly in your shell.
Using .env
Files
Create a .env
file in the root of your project directory. Here, you can define your environment variables:
REACT_APP_API_URL=https://api.example.com
REACT_APP_NOT_SECRET_CODE=abcdef
These variables can then be accessed in your React components using process.env
:
function App() {
return (
API URL: {process.env.REACT_APP_API_URL}
Code: {process.env.REACT_APP_NOT_SECRET_CODE}
);
}
Setting Variables in Your Shell
You can also define environment variables directly in your shell. This method is temporary and will only persist for the duration of the shell session.
For example, on Linux or macOS using Bash:
REACT_APP_API_URL=https://api.example.com REACT_APP_NOT_SECRET_CODE=abcdef
npm start
For Windows (cmd.exe):
set "REACT_APP_API_URL=https://api.example.com" && set "REACT_APP_NOT_SECRET_CODE=abcdef" && npm start
For Windows (PowerShell):
$env:REACT_APP_API_URL="https://api.example.com"; $env:REACT_APP_NOT_SECRET_CODE="abcdef"; npm start
Consuming Environment Variables in a React Component
Here’s an example of how to consume environment variables in a React component:
import React from 'react';
function App() {
return (
<div>
<small>You are running this application in <b>{process.env.NODE_ENV}</b> mode.</small>
<form>
<input type="hidden" defaultValue={process.env.REACT_APP_NOT_SECRET_CODE} />
</form>
</div>
);
}
export default App;
In this example, process.env.NODE_ENV
will be automatically set to development
, test
, or production
based on how you run your React application.
process.env.REACT_APP_NOT_SECRET_CODE
will be replaced with the value defined in your environment.
Conditional Code Based on Environment
You can also use environment variables to conditionally execute code based on the environment:
if (process.env.NODE_ENV !== 'production') {
console.log('Development mode: Analytics disabled');
}
When you build your application for production using npm run build
, this code will be stripped out, resulting in a smaller bundle size.
Referencing Environment Variables in HTML
You can reference environment variables in your public/index.html
file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>%REACT_APP_WEBSITE_NAME%</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
Make sure to follow the guidelines where environment variables must start with REACT_APP_
and are injected at build time. If runtime injection is needed, additional server-side handling is required.
Best Practices for Using Environment Variables in React
Here are some of the ways you can ensure the best use of React environment variables.
Prefix Variables with REACT_APP_
In React, custom environment variables must be prefixed with REACT_APP_
to be recognized during the build process. This requirement is not just a convention but a safeguard that ensures only the intended variables are exposed to the client-side application. Without this prefix, React will ignore the environment variables, leading to potential issues like missing configurations or broken functionality.
Adhering to this naming convention also helps to maintain consistency and clarity across the codebase. It makes it immediately apparent which environment variables are meant for the React application and which are not. For example, REACT_APP_API_KEY
clearly indicates that this key is intended for the React app, whereas an unprefixed variable might be overlooked or misunderstood by other developers.
Handling Different Environments in a Single React Build
Managing different environments in a React application can be challenging, especially when you need to maintain consistency across development, staging, and production. React allows you to handle these variations efficiently by leveraging environment variables and conditional logic.
One common approach is to create multiple .env
files, such as .env.development
, .env.staging
, and .env.production
, each containing the environment-specific variables. React automatically loads the correct file based on the NODE_ENV
value, ensuring that your application behaves appropriately in each environment. For example, you might have different API endpoints, logging levels, or feature flags for each environment, all controlled by these environment variables.
Avoid Direct Access in JSX
Directly referencing environment variables within JSX can lead to cluttered and difficult-to-maintain code. This approach also makes it harder to debug issues related to environment variables since the logic for accessing these variables is intertwined with your UI code. To maintain a clean and modular codebase, it’s best to handle environment variables within the component logic before incorporating them into JSX.
By assigning environment variables to constants or including them within your component’s state or props, you can simplify the JSX and make your code more readable. For instance, instead of embedding process.env.REACT_APP_API_URL
directly in your JSX, you can declare it at the beginning of your component:
const apiUrl = process.env.REACT_APP_API_URL;
This way, your JSX remains clean:
{apiUrl}
This practice not only improves readability but also aids in testing. When environment variables are managed in the component logic, it becomes easier to mock or override them in tests, leading to more robust unit and integration tests.
Access Environment Variables Correctly
Accessing environment variables correctly is crucial for the stability and reliability of your React application. Since environment variables are not always guaranteed to be present, especially when deploying across different environments or working with various team members, it’s essential to handle them with care.
One best practice is to always check for the existence of an environment variable before using it in your application. This can be done by providing default values or using fallback logic. For example:
const apiUrl = process.env.REACT_APP_API_URL || 'https://default.api.com';
This ensures that your application continues to function even if an environment variable is missing or incorrectly configured. Without such checks, your application could crash or behave unpredictably, leading to a poor user experience.
Related content: Read our guide to testing environment
Managing React Environment Variables with Configu
Configu is a configuration management platform comprised of two main components, the stand-alone Orchestrator, which is open source, and the Cloud, which is a SaaS solution:
Configu Orchestrator
As applications become more dynamic and distributed in microservices architectures, configurations are getting more fragmented. They are saved as raw text that is spread across multiple stores, databases, files, git repositories, and third-party tools (a typical company will have five to ten different stores).
The Configu Orchestrator, which is open-source software, is a powerful standalone tool designed to address this challenge by providing confConfigu is a configuration management platform comprised of two main components, the stand-alone Orchestrator, which is open source, and the Cloud, which is a SaaS solution:
Configu Cloud
Configu Cloud is the most innovative store purpose-built for configurations, including environment variables, secrets, and feature flags. It is built based on the Configu configuration-as-code (CaC) approach and can model configurations and wrap them with unique layers, providing collaboration capabilities, visibility into configuration workflows, and security and compliance standardization.
Unlike legacy tools, which treat configurations as unstructured data or key-value pairs, Configu is leading the way with a Configuration-as-Code approach. By modeling configurations, they are treated as first-class citizens in the developers’ code. This makes our solution more robust and reliable and also enables Configu to provide more capabilities, such as visualization, a testing framework, and security abilities.