eduardweb.
Expo & EASIntermediar#react-native#devops#expo#eas#javascript

Cum gestionezi corect secrets în Expo și EAS fără să le scurgi pe GitHub

De Cristian Barbu, 4 aug. 2026 · 6 vizualizări · 2 like-uri

Postat 4 aug. 2026
javascript
module.exports = ({ config }) => {
  const isDev = process.env.APP_ENV === 'development';

  return {
    ...config,
    name: isDev ? "MyApp (Dev)" : "MyApp",
    slug: "my-app",
    ios: {
      bundleIdentifier: isDev ? "ro.eduardweb.app.dev" : "ro.eduardweb.app"
    },
    extra: {
      // Variabilă citită din EAS Secrets sau .env local la build-time
      stripeSecretKey: process.env.STRIPE_SECRET_KEY,
      apiUrl: process.env.EXPO_PUBLIC_API_URL,
      eas: {
        projectId: "12345678-1234-1234-1234-123456789012"
      }
    }
  };
};

Anul trecut am făcut audit la o aplicație Expo cu vreo 15k useri activi și am găsit cheia privată de Stripe plus API key-ul de la Firebase trântite direct în app.json. Mi-a stat inima câteva secunde. Din fericire nu le clonase nimeni rău intenționat, dar am pierdut o zi întreagă rescriind git history-ul și rotind cheile.

Gestionarea variabilelor de mediu în ecosistemul React Native / Expo a fost mereu haotică, dar de când a apărut EAS (Expo Application Services) și prefixul EXPO_PUBLIC_, lucrurile au devenit mai clare. Totuși, văd zilnic confuzii între ce e public, ce e secret de build și ce e secret de runtime.

Regula de aur: EXPO_PUBLIC_ bundlează totul în JS

Dacă o variabilă începe cu EXPO_PUBLIC_, ea ajunge în pachetul final de JavaScript. Oricine decompilează APK-ul sau descarcă IPA-ul poate extrage acel string în 10 secunde folosind un decompiler simplu. Așa că acolo pui doar URL-ul public de API, Supabase Anon Key sau DSN-ul de Sentry.

Pentru mediul local, creezi fișiere .env.development și .env.production. Le pui OBLIGATORIU în .gitignore. Dacă lucrezi cu Expo CLI nativ, el știe să le încarce automat când rulezi npx expo start în funcție de NODE_ENV.

Unde intervin EAS Secrets?

Când dai eas build --profile production, build-ul se execută pe o mașină virtuală în cloud-ul Expo. Mașina aia n-are acces la fișierele tale .env.local nesalvate pe Git. Aici intervin EAS Secrets (sau mai nou, EAS Environment Variables din Dashboard).

Le configurezi simplu din terminal:

eas secret:create --name STRIPE_SECRET_KEY --value sk_live_12345

Trade-off-ul sincer? EAS Secrets sunt ideale pentru securitate și CI/CD fiindcă nu ajung niciodată pe GitHub. În schimb, devine enervant la DX (developer experience): când adaugi o variabilă nouă în proiect, trebuie să o pui în trei locuri (local .env, EAS Secrets staging, EAS Secrets production). Dacă uiți să o pui în EAS, afli abia după 12 minute când crapă build-ul în cloud.

Cum legi totul curat în app.config.js

Ca să folosești variabilele de mediu în configurația aplicației (de exemplu pentru variante de bundle identifier sau chei de la servicii terțe), renunță la app.json și folosește app.config.js sau app.config.ts.

Vezi bucata de cod atașată pentru un setup minimalist dar solid.

În concluzie: ce trebuie să vadă aplicația în browser/mobil folosește EXPO_PUBLIC_, iar ce ține de bucătăria internă de build/backend rămâne în EAS Secrets și este citit prin process.env în app.config.js.

Voi cum gestionați sincronizarea fișierelor .env între membrii echipei? Folosiți eas env:pull, 1Password CLI sau le trimiteți în continuare pe Slack în privat?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

Doar membrii comunității pot lăsa comentarii.