Skip to main content
RapidDev - Software Development Agency
replit-tutorial

How to set environment variables in Replit safely

In Replit, environment variables are managed through the Secrets panel (Tools > Secrets), not through .env files or dotenv packages. To migrate from a .env-based setup, copy each variable into the Secrets panel using the Edit as .env bulk editor, delete the .env file, remove the dotenv dependency, and access values via process.env as usual. Replit provides predefined variables like REPLIT_DEPLOYMENT, REPL_ID, and REPLIT_DOMAINS. Deployment environments require secrets added separately in the Deployments pane.

What you'll learn

  • Migrate from .env files and dotenv to the Replit Secrets panel
  • Use Replit's predefined environment variables (REPLIT_DEPLOYMENT, REPL_ID, etc.)
  • Configure different values for development and production environments
  • Bulk edit environment variables using JSON and .env format editors
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate9 min read15 minutesAll Replit plans with Node.js projectsMarch 2026RapidDev Engineering Team
TL;DR

In Replit, environment variables are managed through the Secrets panel (Tools > Secrets), not through .env files or dotenv packages. To migrate from a .env-based setup, copy each variable into the Secrets panel using the Edit as .env bulk editor, delete the .env file, remove the dotenv dependency, and access values via process.env as usual. Replit provides predefined variables like REPLIT_DEPLOYMENT, REPL_ID, and REPLIT_DOMAINS. Deployment environments require secrets added separately in the Deployments pane.

Manage Environment Variables Securely in Replit for Node.js

This tutorial covers environment variable management in Replit with a focus on Node.js applications. If you are migrating from a local development setup that uses .env files and the dotenv package, this guide shows you how to transition to Replit's Secrets panel. We also cover predefined Replit variables, per-environment configuration strategies, and bulk editing for managing many variables at once. This is for intermediate Node.js developers who want a clean, secure environment variable workflow in Replit.

Prerequisites

  • A Replit account with a Node.js project
  • Existing environment variables you need to manage (API keys, database URLs, etc.)
  • Basic familiarity with Node.js and process.env
  • Optional: an existing .env file to migrate from

Step-by-step guide

1

Migrate your .env file to the Replit Secrets panel

If you have an existing .env file from local development or another platform, open it and copy its contents. Then open the Secrets panel from the Tools dock, click Edit as .env, and paste the contents. This bulk-imports all your environment variables at once. After importing, delete the .env file from your project and remove the dotenv package from your dependencies if present. In Replit, secrets are automatically injected as environment variables, so dotenv is unnecessary and can cause issues if it tries to load a nonexistent .env file.

typescript
1# Your existing .env file might look like this:
2DATABASE_URL=postgresql://user:password@host:5432/mydb
3OPENAI_API_KEY=sk-abc123def456
4JWT_SECRET=my-super-secret-jwt-key
5NODE_ENV=production
6PORT=3000
7
8# Steps:
9# 1. Copy the contents above
10# 2. Open Tools > Secrets > Edit as .env
11# 3. Paste and save
12# 4. Delete the .env file from your project
13# 5. Uninstall dotenv: npm uninstall dotenv
14# 6. Remove require('dotenv').config() from your code

Expected result: All environment variables from your .env file are now in the Secrets panel, and the .env file and dotenv dependency are removed.

2

Remove dotenv references from your code

If your Node.js entry point includes require('dotenv').config() or import dotenv from 'dotenv', remove these lines. Replit injects secrets as environment variables automatically at runtime, so dotenv is redundant. Leaving dotenv in place can cause errors if it looks for a .env file that no longer exists, or worse, it can load stale values from an old .env file that conflicts with your Secrets panel values. Also remove the dotenv package from package.json to keep your dependencies clean.

typescript
1// BEFORE: remove this line
2require('dotenv').config();
3
4// AFTER: no import needed, process.env works directly
5const dbUrl = process.env.DATABASE_URL;
6const port = process.env.PORT || 3000;

Expected result: Your code accesses process.env directly without any dotenv import or configuration.

3

Learn Replit's predefined environment variables

Replit automatically sets several environment variables that you do not need to add to Secrets. REPLIT_DEPLOYMENT is set to '1' when the app runs in a deployed environment and is undefined in the workspace. REPLIT_DOMAINS contains the app's domain name. REPL_ID is the unique identifier for your Repl. REPL_SLUG is the project name. REPL_OWNER is your username. REPLIT_DB_URL is the connection URL for Replit's built-in key-value database. REPLIT_DEV_DOMAIN exists only in the workspace for development URLs. Use these in your code to make environment-aware decisions without adding custom secrets.

typescript
1// Detect environment
2const isProduction = process.env.REPLIT_DEPLOYMENT === '1';
3
4// Get the current domain (works in both workspace and deployment)
5const domain = process.env.REPLIT_DOMAINS;
6
7// Build URLs dynamically
8const baseUrl = isProduction
9 ? `https://${domain}`
10 : `https://${process.env.REPLIT_DEV_DOMAIN}`;
11
12console.log(`Running at ${baseUrl} (${isProduction ? 'production' : 'development'})`);

Expected result: Your code uses predefined variables to detect the environment and construct URLs dynamically.

4

Configure per-environment values for development and production

Many services provide separate test and production credentials (like Stripe's test vs live keys). In Replit, you manage this by storing test credentials in workspace Secrets and production credentials in deployment Secrets. Your code uses REPLIT_DEPLOYMENT to select the correct configuration. You can also store both sets in workspace Secrets with different names (e.g., STRIPE_TEST_KEY and STRIPE_LIVE_KEY) and select the right one in code. The deployment Secrets override workspace Secrets for any matching key names.

typescript
1// config.js — per-environment configuration
2const isProduction = process.env.REPLIT_DEPLOYMENT === '1';
3
4module.exports = {
5 db: {
6 url: process.env.DATABASE_URL,
7 ssl: isProduction,
8 },
9 stripe: {
10 key: isProduction
11 ? process.env.STRIPE_LIVE_KEY
12 : process.env.STRIPE_TEST_KEY,
13 },
14 logging: {
15 level: isProduction ? 'error' : 'debug',
16 },
17 server: {
18 port: parseInt(process.env.PORT || '3000', 10),
19 host: '0.0.0.0',
20 },
21};

Expected result: Your application automatically uses the correct credentials based on whether it is running in the workspace or deployed.

5

Use bulk editing for managing many variables

When your project has many environment variables, individual entry is tedious. The Secrets panel supports two bulk editing modes. Click Edit as JSON to enter a JSON object where keys are variable names and values are the variable values. Click Edit as .env to enter standard KEY=VALUE format, one per line. Both modes let you add, update, or remove multiple variables at once. This is especially useful when copying configurations between projects or when a team member needs to set up the same environment. For teams managing complex configurations across multiple Replit projects, RapidDev can help establish standardized environment variable workflows.

typescript
1// JSON format for bulk editing
2{
3 "DATABASE_URL": "postgresql://user:pass@host:5432/db",
4 "OPENAI_API_KEY": "sk-abc123",
5 "JWT_SECRET": "long-random-string-here",
6 "REDIS_URL": "redis://localhost:6379",
7 "SMTP_HOST": "smtp.sendgrid.net",
8 "SMTP_USER": "apikey",
9 "SMTP_PASS": "SG.xxxxxxxxxxxx",
10 "NODE_ENV": "production"
11}

Expected result: Multiple environment variables are created or updated in one operation through the bulk editor.

6

Verify secrets are loaded correctly in your application

After setting up your environment variables, create a startup validation routine that checks all required variables are present. This runs when your app starts and immediately tells you if something is missing. Never log actual secret values. Instead, log whether each required secret is set (truthy) or missing. Run your app with the Run button and check the Console output. If any variables are missing, add them in the Secrets panel and restart.

typescript
1// startup-check.js — import at the top of your entry point
2const REQUIRED = [
3 'DATABASE_URL',
4 'JWT_SECRET',
5 'OPENAI_API_KEY',
6];
7
8const OPTIONAL = [
9 'SMTP_HOST',
10 'REDIS_URL',
11];
12
13const isProduction = process.env.REPLIT_DEPLOYMENT === '1';
14const context = isProduction ? 'Deployments > Secrets' : 'Tools > Secrets';
15
16const missing = REQUIRED.filter(key => !process.env[key]);
17if (missing.length > 0) {
18 console.error(`\nMissing required env vars (add in ${context}):`);
19 missing.forEach(key => console.error(` - ${key}`));
20 if (isProduction) process.exit(1);
21}
22
23const missingOptional = OPTIONAL.filter(key => !process.env[key]);
24if (missingOptional.length > 0) {
25 console.warn(`\nOptional env vars not set: ${missingOptional.join(', ')}`);
26}
27
28console.log(`Environment check passed (${isProduction ? 'production' : 'development'})`);

Expected result: Your application logs a clear status of all environment variables at startup, with errors for missing required values.

Complete working example

index.js
1/**
2 * Node.js application with secure environment variable management
3 * All secrets stored in Replit Secrets panel (Tools > Secrets)
4 * No .env files, no dotenv package
5 */
6
7// Startup validation (runs before anything else)
8const isProduction = process.env.REPLIT_DEPLOYMENT === '1';
9const envContext = isProduction ? 'Deployments > Secrets' : 'Tools > Secrets';
10
11const requiredVars = ['DATABASE_URL', 'JWT_SECRET'];
12const missing = requiredVars.filter(v => !process.env[v]);
13if (missing.length > 0) {
14 console.error(`Missing env vars (add in ${envContext}): ${missing.join(', ')}`);
15 if (isProduction) process.exit(1);
16}
17
18// Application code
19const express = require('express');
20const app = express();
21
22const config = {
23 port: parseInt(process.env.PORT || '3000', 10),
24 dbUrl: process.env.DATABASE_URL,
25 jwtSecret: process.env.JWT_SECRET,
26 openaiKey: process.env.OPENAI_API_KEY || null,
27 environment: isProduction ? 'production' : 'development',
28 domain: process.env.REPLIT_DOMAINS || 'localhost',
29};
30
31app.use(express.json());
32
33app.get('/api/health', (req, res) => {
34 res.json({
35 status: 'ok',
36 environment: config.environment,
37 features: {
38 openai: !!config.openaiKey,
39 },
40 });
41});
42
43app.get('/api/env-info', (req, res) => {
44 // Safe: returns metadata, never actual secret values
45 res.json({
46 replId: process.env.REPL_ID,
47 replSlug: process.env.REPL_SLUG,
48 owner: process.env.REPL_OWNER,
49 isDeployed: isProduction,
50 domain: config.domain,
51 });
52});
53
54app.listen(config.port, '0.0.0.0', () => {
55 console.log(`Server running on port ${config.port} (${config.environment})`);
56 console.log(`Domain: ${config.domain}`);
57});

Common mistakes when setting environment variables in Replit safely

Why it's a problem: Keeping both a .env file and Secrets panel entries, causing confusion about which values are used

How to avoid: Delete the .env file entirely. Replit's Secrets panel is the single source of truth. The .env file is visible in public Repls and is not encrypted.

Why it's a problem: Using require('dotenv').config() in Replit

How to avoid: Remove dotenv. Run npm uninstall dotenv and delete the require/import statement. Replit injects secrets as environment variables automatically.

Why it's a problem: Using REPLIT_DEV_DOMAIN in production code

How to avoid: REPLIT_DEV_DOMAIN only exists in the workspace and is undefined in deployments. Use REPLIT_DOMAINS instead, which works in both environments.

Why it's a problem: Logging process.env to debug missing variables, which prints all secret values

How to avoid: Instead of console.log(process.env), check individual variables: console.log('DB set:', !!process.env.DATABASE_URL). This confirms presence without exposing values.

Why it's a problem: Expecting secrets added during runtime to be available without restarting

How to avoid: New secrets are not picked up by running processes. Click Stop then Run to restart your app, or run kill 1 in Shell to reload the environment.

Best practices

  • Never use .env files or the dotenv package in Replit. Use the Secrets panel exclusively.
  • Add deployment secrets separately from workspace secrets in the Deployments pane
  • Validate all required environment variables at startup with clear error messages
  • Use REPLIT_DEPLOYMENT to detect production vs development and select appropriate configurations
  • Never log actual secret values. Log only whether they are set or missing.
  • Use consistent naming conventions: UPPERCASE_WITH_UNDERSCORES for all environment variable names
  • Use the bulk editor (Edit as JSON or Edit as .env) for efficient management of many variables
  • Keep a documented list of all required and optional environment variables for your project

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I am migrating a Node.js project to Replit. It currently uses a .env file with dotenv. Show me how to: 1) Transfer all variables to Replit Secrets, 2) Remove dotenv cleanly, 3) Set up a config module that uses process.env with REPLIT_DEPLOYMENT for environment detection, 4) Configure separate development and production values.

Replit Prompt

Migrate my project from .env files to Replit Secrets. Remove all dotenv references, create a config.js module that validates required environment variables at startup, and set up environment detection using REPLIT_DEPLOYMENT. Show me which variables need to go in workspace Secrets vs deployment Secrets.

Frequently asked questions

No. Replit automatically injects secrets as environment variables at runtime. The dotenv package is unnecessary and can cause issues if it looks for a .env file that does not exist. Remove it with npm uninstall dotenv.

Workspace secrets are available when you click Run in the editor. Deployment secrets are used by your deployed app (Autoscale, Reserved VM, Scheduled). They are configured separately and can have different values, such as test vs production API keys.

Replit sets REPLIT_DEPLOYMENT (1 in deployed apps), REPLIT_DOMAINS (app domain), REPL_ID, REPL_SLUG, REPL_OWNER, REPLIT_DB_URL (key-value DB), and REPLIT_DEV_DOMAIN (workspace only, not in deployments).

Store test credentials in workspace Secrets and production credentials in deployment Secrets. Use process.env.REPLIT_DEPLOYMENT === '1' in your code to detect the environment and select the correct configuration.

Yes. Open the Secrets panel, click Edit as .env, and paste the contents of your .env file. All variables are imported at once. Then delete the .env file from your project.

Yes. RapidDev helps teams establish consistent environment variable conventions, set up validation frameworks, and manage multi-project configurations. They can create standardized config modules and documentation for your team's Replit workflow.

Running processes do not automatically pick up new secrets. Restart your app by clicking Stop then Run, or run kill 1 in Shell. Also verify you are checking the correct Secrets location: workspace Secrets for development, deployment Secrets for deployed apps.

Yes. You can set non-sensitive environment variables under [run.env] in the .replit file. However, never put API keys or sensitive values there since the .replit file is part of your source code and visible in public Repls. Use the Secrets panel for all sensitive values.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.