How to Set Up .env Files - Complete Guide

How-To Guide

How to Set Up .env Files

Your secrets live in one file. Here's how to set it up right.

TL;DR

Create a .env.local file in your project root with KEY=value pairs and add it to .gitignore. Most modern frameworks (Next.js, Vite) load .env files automatically. For plain Node.js, install dotenv and import it at the very top of your entry file.

File Naming Conventions

FilePurposeCommit to Git?
.envBase defaultsSometimes (no secrets)
.env.localLocal overrides with secretsNever
.env.developmentDevelopment environmentSometimes
.env.productionProduction environmentNever
.env.exampleTemplate with placeholder valuesYes

Step-by-Step Setup

1

Create your .env.local file

In your project root, create .env.local:

# .env.local

# Database
DATABASE_URL=postgresql://localhost:5432/mydb

# API Keys
STRIPE_SECRET_KEY=sk_test_xxxxx
OPENAI_API_KEY=sk-xxxxx

# Public variables (exposed to browser in Next.js)
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
NEXT_PUBLIC_API_URL=http://localhost:3000/api
2

Add to .gitignore

Don't commit .env files with real secrets. Add these patterns:

# .gitignore

# Environment files
.env
.env.local
.env.*.local
.env.production

# Keep the example
!.env.example
3

Create an example file

.env.example acts as the template for anyone cloning your repo. Commit this one:

# .env.example - Copy to .env.local and fill in values

DATABASE_URL=postgresql://user:password@localhost:5432/dbname
STRIPE_SECRET_KEY=sk_test_your_key_here
OPENAI_API_KEY=sk-your_key_here
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co

Framework-Specific Setup

Next.js

Next.js loads .env files automatically. No installation needed.

// Access in server components, API routes, etc.
const apiKey = process.env.STRIPE_SECRET_KEY;

// Access in client components (must have NEXT_PUBLIC_ prefix)
const apiUrl = process.env.NEXT_PUBLIC_API_URL;

Vite (React, Vue, Svelte)

Vite loads .env files automatically too, but uses a different prefix:

# .env.local
VITE_API_URL=https://api.example.com

// Access in code
const apiUrl = import.meta.env.VITE_API_URL;

Node.js (Express, etc.)

For plain Node.js, you'll need to install the dotenv package:

npm install dotenv

Then import it at the very top of your entry file. It must load before any other imports that read process.env:

// index.js or server.js - MUST be first import
import 'dotenv/config';
// or: require('dotenv').config();

// Now process.env has your variables
const port = process.env.PORT || 3000;
const dbUrl = process.env.DATABASE_URL;

Create React App

CRA uses REACT_APP_ as its prefix (not VITE_):

# .env.local
REACT_APP_API_URL=https://api.example.com

// Access in code
const apiUrl = process.env.REACT_APP_API_URL;

.env File Syntax

# Comments start with #
# Basic format: KEY=value (no spaces around =)

# Simple values
PORT=3000
NODE_ENV=development

# Strings with spaces need quotes
APP_NAME="My Awesome App"

# URLs don't need quotes
API_URL=https://api.example.com/v1

# Multi-line values use quotes
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA
-----END RSA PRIVATE KEY-----"

# Reference other variables (in some implementations)
BASE_URL=https://api.example.com
FULL_URL=${BASE_URL}/v1

Common syntax mistakes: spaces around = (KEY = value breaks parsing), missing quotes when the value has spaces (NAME=My App should be NAME="My App"), and trailing whitespace after the value (invisible but causes strange auth failures).

Loading Order

Most frameworks load .env files in this order (later files override earlier ones):

  1. .env
  2. .env.local
  3. .env.development or .env.production (based on NODE_ENV)
  4. .env.development.local or .env.production.local

Use .env.local for local secrets and .env for shared, non-sensitive defaults. That way teammates can commit .env with placeholder port numbers and you keep your real API keys out of git entirely.

Do I need to restart my dev server after changing .env?

Yes. Environment variables are loaded when your application starts. After changing .env.local, restart your dev server with npm run dev or equivalent.

Why isn't my variable showing up?

Start with the dev server restart. That's the culprit 80% of the time. If it's still missing, check that you put it in .env.local and not just .env. For browser-facing variables, confirm you're using the right prefix for your framework: NEXT_PUBLIC_ for Next.js, VITE_ for Vite, REACT_APP_ for CRA.

Should I commit .env files?

Never commit files with real secrets. .env.example is always safe to commit (it has placeholder values, not real ones). You can also commit a .env that contains only non-sensitive defaults like PORT=3000 or NODE_ENV=development. Keep .env.local and anything with real credentials out of git.

Related guides:Environment Variables Guide · How to Gitignore Secrets · How to Hide API Keys

How-To Guides

How to Set Up .env Files - Complete Guide