GuideCode & export
Code & exportIntermediate8 min

Environment variables

Keep secrets out of your code. Every API key, database URL, and third-party credential belongs in environment variables — not hardcoded.

Why env vars matter

An environment variable is a named value that exists in the runtime environment of your app — separate from its source code. When your app needs an API key, a database connection string, or a third-party webhook secret, it reads that value from the environment at startup rather than finding it hardcoded in a file.

This separation matters for two reasons. First, secrets that live in code end up in version control. A single accidental push to a public GitHub repository can expose credentials to the entire internet, and rotation after an exposure is painful. Second, different environments — development on your laptop, staging for QA, production for real users — need different values for the same variable. Environment variables make that switch trivial.

Watch out.Never paste API keys, database passwords, or OAuth secrets directly into a Myndlab prompt. Prompts are stored in your build history. Keep all credentials in environment variables where access is controlled.

Setting variables in Myndlab

Every Myndlab project has an Environment panel where you define your variables. To access it:

1
Open Project Settings
Click the settings icon in the top-right corner of the Build screen, or press ⌘ K and type 'Project Settings'.
2
Select the Environment tab
You'll see two sections: Development and Production. Each has its own independent set of variables.
3
Add a variable
Click 'Add variable'. Enter the variable name in the Key field (uppercase with underscores is the convention: STRIPE_SECRET_KEY, DATABASE_URL) and the value in the Value field. Click the eye icon to toggle whether the value is masked in the UI.
4
Save
Click Save. The variable is immediately available in your next build and deploy. You do not need to trigger a new code generation — Myndlab injects environment variables at deploy time, not code-gen time.
Note.Variable names are case-sensitive. STRIPE_SECRET_KEY and stripe_secret_key are treated as two different variables. The convention is ALL_CAPS_WITH_UNDERSCORES for all environment variables, in all languages.

Dev vs production values

Myndlab maintains separate variable stores for Development and Production environments. This lets you use a test Stripe key and a local database URL during development, while your production environment uses live credentials and your cloud database — without any code changes.

1
Development variables
Used when you preview your app inside Myndlab's built-in preview window and when you run the project locally after exporting or syncing to GitHub. Set these to test/sandbox credentials from your API providers — Stripe test keys, a Mailgun sandbox domain, a local Postgres instance URL.
2
Production variables
Used when Myndlab deploys to your live hosting target (Vercel, Railway, Fly.io, etc.). Set these to your live API credentials. Production variables are never exposed in generated code or GitHub commits.
3
Shared variables
Variables you mark as Shared are copied to both environments automatically. Use this for non-secret configuration that is identical across environments — for example, APP_NAME or a feature flag that applies everywhere.

When Myndlab pushes a deploy to Vercel or Railway, it injects the Production variables directly into the hosting platform's secret store via their APIs. You never need to copy-paste credentials into a hosting dashboard manually.

Referencing vars in generated code

Myndlab generates code that reads environment variables using each language's idiomatic pattern. Here are the two most common cases:

In a FastAPI (Python) backend, variables are loaded with the standard library:

python
import os
from fastapi import FastAPI

app = FastAPI()

# Loaded from the environment at startup — never hardcoded
DATABASE_URL = os.environ.get("DATABASE_URL")
STRIPE_SECRET_KEY = os.environ.get("STRIPE_SECRET_KEY")
OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")

if not DATABASE_URL:
    raise RuntimeError(
        "DATABASE_URL environment variable is not set. "
        "Add it in Project Settings > Environment."
    )

@app.get("/health")
def health():
    return {"status": "ok"}

In a React frontend (Vite), variables must be prefixed with VITE_ to be exposed to the browser bundle. This prefix is a security measure — variables without it are never included in the client-side code, even if they exist in the environment.

typescript
// Vite exposes only VITE_-prefixed variables to the browser
const apiBaseUrl = import.meta.env.VITE_API_BASE_URL;
const stripePublicKey = import.meta.env.VITE_STRIPE_PUBLISHABLE_KEY;

// Never put secrets in VITE_ variables — they're visible in the browser
// Use VITE_ only for public, non-sensitive configuration

if (!apiBaseUrl) {
  console.error(
    "VITE_API_BASE_URL is not set. " +
    "Check Project Settings > Environment."
  );
}
Watch out.Never put secret keys (Stripe secret key, database passwords, private API tokens) in VITE_ variables. Because VITE_-prefixed variables are bundled into the JavaScript that ships to browsers, they are visible to anyone who opens DevTools. Use them only for public configuration like your API's base URL or a Stripe publishable key.

In an Express (Node.js) backend, the pattern is similar to Python but uses process.env:

typescript
import express from "express";

const app = express();

const DATABASE_URL = process.env.DATABASE_URL;
const JWT_SECRET = process.env.JWT_SECRET;

if (!DATABASE_URL || !JWT_SECRET) {
  throw new Error(
    "Required environment variables are missing. " +
    "Check Project Settings > Environment."
  );
}

app.listen(process.env.PORT ?? 3001, () => {
  console.log("Server started");
});

Syncing to GitHub

When Myndlab syncs your project to GitHub, environment variables are handled carefully to prevent accidental exposure:

1
A .env.example file is committed
Myndlab generates a .env.example file containing all your variable names with empty or placeholder values. This file is committed to GitHub so that anyone cloning the repository knows exactly which variables they need to configure, without seeing any actual secrets.
2
The real .env file is never committed
Myndlab adds .env and .env.local to .gitignore automatically. Your actual variable values never appear in the repository, in the git history, or in any pull request diff.
3
GitHub Actions secrets (optional)
If you use Myndlab's GitHub Actions CI integration, production variables are pushed to GitHub Actions Secrets via the GitHub API during your first deploy. Subsequent CI runs read from those secrets — you don't manage them manually in the GitHub web UI.
bash
# .env.example — committed to GitHub (no real values)
DATABASE_URL=
STRIPE_SECRET_KEY=
STRIPE_PUBLISHABLE_KEY=
OPENAI_API_KEY=
JWT_SECRET=
APP_URL=http://localhost:3000

# .env — local only, never committed (in .gitignore)
DATABASE_URL=postgresql://postgres:password@localhost:5432/myapp_dev
STRIPE_SECRET_KEY=sk_test_...
STRIPE_PUBLISHABLE_KEY=pk_test_...
OPENAI_API_KEY=sk-...
JWT_SECRET=a-long-random-string-here
APP_URL=http://localhost:3000

Rotating a secret

Secret rotation — replacing a compromised or expired credential with a new one — should be done carefully to avoid downtime. Here is the safe sequence to follow in Myndlab:

1
Generate the new secret with your provider
Create the new API key or password in the external service's dashboard first. Don't revoke the old one yet — your live app is still using it.
2
Update the Production variable in Myndlab
Go to Project Settings > Environment > Production. Click the variable you're rotating, paste the new value, and save. Myndlab does not push this change to your hosting platform until a deploy is triggered.
3
Trigger a deploy
Press ⌘ Enter and confirm the deploy, or click Deploy in the Build screen. Myndlab pushes the new variable value to your hosting platform as part of the deploy. The new value becomes active when the deploy completes (usually under 60 seconds for most platforms).
4
Verify the app is healthy
Check your app's health endpoint or run a quick smoke test — log in, perform a key action — to confirm the new credential is working correctly.
5
Revoke the old secret
Only now, once you've confirmed the app is healthy with the new credential, go back to your provider's dashboard and revoke the old secret. This sequence ensures zero-downtime rotation.
💡
Tip.If you suspect a secret has been compromised, prioritise revoking it immediately — even before you have a replacement ready. A brief window of degraded functionality (for example, Stripe payments failing) is far less damaging than a live credential in an attacker's hands. Set up the new credential and restore service as quickly as possible after revocation.