.md

Expo

Encrypt a .env file in Expo with Dotenvx, share access with your team, and load configuration before bundling.

Prerequisites

Create an Expo app.

Expo bundles EXPO_PUBLIC_ values into your app. Encryption protects your .env files in git; it does not make shipped app values private. Keep real secrets on your backend or in build tooling.

Install

Install Dotenvx in your Expo project:

$ npm install @dotenvx/dotenvx
$ pnpm add @dotenvx/dotenvx

Encrypt

Start with a demonstration value in the .env file at your project root:

# .env
EXPO_PUBLIC_HELLO="Secret"

Encrypt it with a single command.

$ npx dotenvx encrypt
◈ encrypted .env (022 0D8) via .env.keys ⛉
$ pnpm exec dotenvx encrypt
◈ encrypted .env (022 0D8) via .env.keys ⛉

The values become ciphertext and only your private key can unlock them.

# .env
DOTENV_PUBLIC_KEY="0220d830351410598be484f43a7b07097e09851f50426832876e8b5815a1752990"

EXPO_PUBLIC_HELLO="encrypted:BHLTACNJMr00nTG6yXpkCyWFKF/MY0ajN855tg3uVtKopTe2AGzSkQlcPd21pTOT3Ci8IKrdIg2TMZFoq1mDR6yb06QCRvqHXtpkZkAHYCEHfeWqqC8tMFovcYq5JS2uZSrC/qUGDA=="

Commit

Commit your encrypted .env files with your code. It's safe. Now you can securely share secrets through git.

$ git add .env
$ git commit -m "encrypt .env"

Ship

Read the value in a screen. For example, replace your Expo Router home screen with:

// app/index.tsx (or your existing home route)
import { Text, View } from 'react-native';

export default function Home() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Hello {process.env.EXPO_PUBLIC_HELLO}</Text>
    </View>
  );
}

Use the full process.env.EXPO_PUBLIC_HELLO reference so Expo can inline it. Do not destructure process.env or use bracket notation.

Update these scripts in package.json, keeping your other scripts:

{
  "scripts": {
    "start": "dotenvx run -e EXPO_NO_DOTENV=1 -f .env --strict -- expo start",
    "android": "dotenvx run -e EXPO_NO_DOTENV=1 -f .env --strict -- expo start --android",
    "ios": "dotenvx run -e EXPO_NO_DOTENV=1 -f .env --strict -- expo start --ios",
    "web": "dotenvx run -e EXPO_NO_DOTENV=1 -f .env --strict -- expo start --web",
    "export": "dotenvx run -e EXPO_NO_DOTENV=1 -f .env.production --strict -- expo export"
  }
}

The -e flag sets EXPO_NO_DOTENV to disable Expo's own .env loader. Dotenvx loads and decrypts the selected file before Expo starts.

Run your app:

$ npm start
⟐ injected env (3) from .env (022 0D8) via .env.keys
$ pnpm start
⟐ injected env (3) from .env (022 0D8) via .env.keys

Open the app in Expo Go or your development build to see Hello Secret. Restart the command and reload the app after changing .env.

Build-only secrets Alternative →

Share

Have teammates? Share access with Dotenvx Armor ⛨

Log in to Dotenvx.

$ npx dotenvx login
◉ logged in (username)
$ pnpm exec dotenvx login
◉ logged in (username)

Create the Armored Key ⛨

$ npx dotenvx armor up
⛨ armored .env (022 0D8)
$ pnpm exec dotenvx armor up
⛨ armored .env (022 0D8)

Invite your teammate.

$ npx dotenvx armor invite
⛨ invited [email protected] to team
$ pnpm exec dotenvx armor invite
⛨ invited [email protected] to team

Your teammate accepts the invitation, pulls the repository, installs dependencies, and logs in with dotenvx login. They can then run the app:

$ npm start
⟐ injected env (3) from .env (022 0D8) via Armor ⛨
$ pnpm start
⟐ injected env (3) from .env (022 0D8) via Armor ⛨

Open the app to see Hello Secret.

Share a private key Alternative →

Production

Create a .env.production file:

# .env.production
EXPO_PUBLIC_HELLO="Production"

Encrypt it:

$ npx dotenvx encrypt -f .env.production
$ pnpm exec dotenvx encrypt -f .env.production

For a local export, choose Local when prompted and store the key in .env.keys. Keep .env.keys out of git.

Commit the encrypted file:

$ git add -f .env.production
$ git commit -m "encrypt .env.production"

Export the production bundle:

$ npm run export
$ pnpm export

Dotenvx decrypts .env.production on the build machine. Expo embeds the public value in the output under dist. The app does not need Dotenvx or a private key on the device.

This creates bundles, not an installable native app. Continue with EAS Build for a native build or EAS Update for an update to a compatible installed app.

EAS Build Alternative →

EAS Update Alternative →

Conclusion

You've encrypted your configuration, shared access with Armor, and loaded production values before Expo bundles your app. Your encrypted files travel with your code; private keys stay on development and build machines.

Open page ↗

Side path