Learn how to use environment variables in your Expo project.
Environment variables are key-value pairs configured outside your source code that allow your app to behave differently depending on the environment. For example, you can enable or disable certain features when building a test version of your app, or switch to a different API endpoint when building for production.
Create a .env file in the root of your project directory:
# .env
EXPO_PUBLIC_API_URL=https://staging.example.com
EXPO_PUBLIC_API_KEY=abc123Access environment variables using process.env.EXPO_PUBLIC_[NAME]:
import { Button } from 'react-native';
function Post() {
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
async function onPress() {
await fetch(apiUrl, { ... });
}
return <Button onPress={onPress} title="Post" />;
}All environment variables used in JavaScript code must be prefixed with EXPO_PUBLIC_:
# ✅ Correct
EXPO_PUBLIC_API_URL=https://api.example.com
# ❌ Wrong - won't be available in JavaScript
API_URL=https://api.example.comEnvironment variables must be statically referenced using dot notation:
// ✅ Correct - will be inlined
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
// ❌ Wrong - won't be inlined
const apiUrl = process.env['EXPO_PUBLIC_API_URL'];
// ❌ Wrong - won't be inlined
const { EXPO_PUBLIC_API_URL } = process.env;You can use multiple .env files for different environments:
.env # Default (can be committed)
.env.local # Local overrides (should be gitignored)
.env.development # Development environment
.env.production # Production environment
Files are loaded in this priority order (later files override earlier ones):
.env.env.local.env.[NODE_ENV].env.[NODE_ENV].local
Add .env*.local to your .gitignore:
# .gitignore
.env*.localThis prevents committing local environment-specific configurations.
# Default/development values
EXPO_PUBLIC_API_URL=https://api.staging.example.com
EXPO_PUBLIC_ENABLE_ANALYTICS=false# Local overrides
EXPO_PUBLIC_API_URL=http://localhost:3000# Production values
EXPO_PUBLIC_API_URL=https://api.example.com
EXPO_PUBLIC_ENABLE_ANALYTICS=trueFor TypeScript, you can create a type definition file:
// types/env.d.ts
declare namespace NodeJS {
interface ProcessEnv {
EXPO_PUBLIC_API_URL: string;
EXPO_PUBLIC_API_KEY: string;
EXPO_PUBLIC_ENABLE_ANALYTICS: string;
}
}EAS Build uses Metro Bundler to build your JavaScript bundle, so it will use .env files uploaded with your build job. You can also define environment variables in eas.json:
{
"build": {
"production": {
"env": {
"EXPO_PUBLIC_API_URL": "https://api.example.com"
}
}
}
}EAS Update uses Metro Bundler in your local environment or CI, so it will use available .env files.
For sensitive values, use EAS Secrets instead of environment variables:
eas secret:create --scope project --name EXPO_PUBLIC_API_KEY --value your-secret-keyIf you need to disable environment variable loading:
EXPO_NO_DOTENV=1 npx expo startEXPO_NO_CLIENT_ENV_VARS=1 npx expo start
⚠️ Important: Never store sensitive information inEXPO_PUBLIC_variables!
- Private keys
- API secrets
- Database passwords
- Authentication tokens
- Any sensitive credentials
Variables prefixed with EXPO_PUBLIC_ are:
- Embedded in your compiled JavaScript bundle
- Visible in plain text
- Accessible to anyone who inspects your app
- Public API endpoints (non-sensitive)
- Feature flags
- Public configuration values
- Build-time constants
Use:
- EAS Secrets for build-time secrets
- SecureStore for runtime secrets (see Store Data Guide)
- Backend API for sensitive operations
- Update
.envfiles to prefix variables withEXPO_PUBLIC_:
# Before
API_URL=https://myapi.com
# After
EXPO_PUBLIC_API_URL=https://myapi.com- Update your code:
// Before
import Config from 'react-native-config';
const apiUrl = Config.API_URL;
// After
const apiUrl = process.env.EXPO_PUBLIC_API_URL;- Remove
react-native-configfrom dependencies:
npm uninstall react-native-config- Update variable names to use
EXPO_PUBLIC_prefix - Remove the plugin from
babel.config.js:
module.exports = function (api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
// Remove this line:
// plugins: ['transform-inline-environment-variables'],
};
};- Clear cache:
npx expo start --clear- Use Descriptive Names: Make variable names clear and descriptive
- Document Variables: Add comments in
.envfiles explaining what each variable does - Use .env.local for Secrets: Keep sensitive local overrides in
.env.local(gitignored) - Validate Variables: Check that required variables exist at runtime
- Type Safety: Use TypeScript definitions for better IDE support
- Default Values: Provide sensible defaults when possible
const getApiUrl = () => {
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
if (!apiUrl) {
throw new Error('EXPO_PUBLIC_API_URL is not defined');
}
return apiUrl;
};- Full Reload: Shake device → Reload (or press
rin terminal) - Clear Cache:
npx expo start --clear - Check Prefix: Ensure variables start with
EXPO_PUBLIC_ - Check Syntax: Use dot notation, not bracket notation
- Check File Location:
.envmust be in project root - Check Prefix: Must use
EXPO_PUBLIC_prefix - Check Reference: Must use
process.env.EXPO_PUBLIC_[NAME]syntax - Restart Expo: Stop and restart
npx expo start