Skip to content

Remix Environment Variables — Configuration Management

DodaTech Updated 2026-06-28 3 min read

In this tutorial, you will learn about Remix Environment Variables. We cover key concepts, practical examples, and best practices to help you master this topic.

Learn Remix environment variables: manage secrets, configure for development and production, expose to the client, and use .env files for configuration.

In this lesson, you'll manage environment variables in Remix, differentiate between server-only and client-safe variables, and set up different configurations per environment.

What You'll Learn

How to use .env files, access server-only variables, expose variables to the client, and set up deployment-specific configuration.

Why It Matters

Environment variables keep secrets out of your codebase and let your app behave differently in development, staging, and production without code changes.

Real-World Use

DodaZIP uses environment variables for API keys, database URLs, and feature flags across multiple deployment environments.

flowchart LR
    A[.env] --> B[Remix App]
    B --> C[Server Env Vars]
    B --> D[Client Env Vars]
    C --> E[Secrets, DB, APIs]
    D --> F[Public Config, URLs]
    style B fill:#121212,color:#fff

Using .env Files

Create .env in the project root:

DATABASE_URL="postgresql://localhost:5432/myapp"
SESSION_SECRET="your-secret-key"
PUBLIC_API_URL="https://api.example.com"
STRIPE_API_KEY="sk_live_..."

Remix loads these automatically in development.

Server-Only Variables

Access any environment variable on the server:

// In loaders or actions
export const loader = async () => {
  const dbUrl = process.env.DATABASE_URL;
  const stripeKey = process.env.STRIPE_API_KEY;

  // Use them securely (never exposed to client)
  const data = await queryDatabase(dbUrl);
  return json(data);
};

Client-Safe Variables

Variables must be prefixed with PUBLIC_ to be available on the client:

// Only PUBLIC_ prefixed variables are available on the client
const apiUrl = process.env.PUBLIC_API_URL;
const gaId = process.env.PUBLIC_GA_ID;

export default function App() {
  return (
    <div>
      <p>API URL: {process.env.PUBLIC_API_URL}</p>
      {/* process.env.STRIPE_API_KEY is undefined here */}
    </div>
  );
}

Validation

Validate required variables at startup:

// app/env.server.ts
function requireEnv(name: string): string {
  const value = process.env[name];
  if (!value) {
    throw new Error(`Missing required environment variable: ${name}`);
  }
  return value;
}

export const env = {
  DATABASE_URL: requireEnv("DATABASE_URL"),
  SESSION_SECRET: requireEnv("SESSION_SECRET"),
  PUBLIC_API_URL: process.env.PUBLIC_API_URL || "http://localhost:3000",
};

Deployment Configuration

# Production (set in hosting dashboard or CI)
DATABASE_URL="postgresql://prod-db:5432/myapp"
SESSION_SECRET="prod-secret"
PUBLIC_API_URL="https://api.example.com"

# Staging
DATABASE_URL="postgresql://staging-db:5432/myapp"
PUBLIC_API_URL="https://staging-api.example.com"

Common Mistakes

  1. Exposing secrets to the client: Never access Process.env.SECRET in client components. It's undefined and you might accidentally expose fallback values.
  2. Committing .env files: Add .env to .gitignore. Use .env.example as a template with placeholder values.
  3. Not validating required variables: Your app may start but fail later when a missing env var is accessed. Validate on startup.
  4. Using different variable names across environments: Keep variable names consistent. Use the same name for the same value in dev, staging, and prod.
  5. Hardcoding fallback values in code: Use environment variables for all configurable values. Hardcoded fallbacks cause unexpected behavior.

Practice Questions

  1. How do you make a variable available on the client? Answer: Prefix it with PUBLIC_. Only variables with this prefix are accessible in client components.

  2. How does Remix load .env files? Answer: Automatically in development. In production, variables are set in the hosting platform's environment configuration.

  3. What happens if you access a server-only variable on the client? Answer: It returns undefined. The variable is not included in the client bundle.

  4. Why should you validate env vars at startup? Answer: To fail early with a clear error message instead of failing later with a confusing error when the variable is accessed.

Challenge

Set up a multi-environment app with different API URLs for development, staging, and production. Create validation that checks all required variables exist at startup.

Mini Project

Create a feature flag system using environment variables. Features like "new-dashboard", "beta-search", and "dark-mode" should be toggleable via env vars without code deployment.

FAQ

How do I use `.env.local` for local overrides?

: Remix supports .env.local automatically. Variables in .env.local override .env for local development.

Can I use environment variables in `remix.config.js`?

: Yes. The config file has access to process.env during build time.

How do I set variables in Vercel/Netlify/Cloudflare?

: Use the hosting platform's dashboard or CLI to set environment variables for each deployment environment.

Are build-time and runtime env vars the same?

: No. Build-time variables (used in config) are baked into the build. Runtime variables are available when the server runs.

What's Next

Learn about Remix Deployment for deploying Remix apps to production hosting.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro