Facebook Pixel

Environment Variables vs Hardcoded Config Why You Should Never Hardcode Secrets

Learn why environment variables are superior to hardcoded configuration in Node.js security, flexibility, portability, and the 12-factor app methodology.

Environment Variables vs Hardcoded Config

Hardcoding configuration and secrets in your code is a serious security risk. This guide explains why environment variables are the standard.

The Problem with Hardcoding

// WRONG hardcoded config const MONGODB_URI = "mongodb://user:[email protected]/devtinder"; const JWT_SECRET = "mysecret123"; const STRIPE_KEY = "sk_live_abc123"; app.listen(3000, () => { console.log("Server running on port 3000"); });

Issues:

  1. Security Secrets are in Git history forever
  2. Inflexibility Can't change without code modification
  3. No environments Same config for dev and prod
  4. Team conflicts Everyone shares the same secrets
  5. Deployment complexity Need different code for each environment

The Solution: Environment Variables

// RIGHT environment variables const config = require("./config"); app.listen(config.port, () => { console.log(`Server running on port ${config.port}`); }); // config/index.js require("dotenv").config(); module.exports = { port: process.env.PORT || 3000, mongoUri: process.env.MONGODB_URI, jwtSecret: process.env.JWT_SECRET, stripeKey: process.env.STRIPE_KEY };

Benefits:

  1. Security Secrets not in code or Git
  2. Flexibility Change config without code changes
  3. Multiple environments Different .env per environment
  4. Team-friendly Each developer has own .env
  5. Easy deployment Same code, different .env

The 12-Factor App Methodology

The 12-factor app methodology (created by Heroku) defines best practices for modern web apps. Factor 3: Config should be stored in environment variables.

Code = Logic (same across all environments)
Config = Variables that change between environments

Configuration includes:

  • Database connection strings
  • API keys and secrets
  • Port numbers
  • External service URLs
  • Feature flags
  • Logging levels

When to Use Environment Variables

Always use env vars for:

  • Database connection strings
  • API keys (Stripe, AWS, Google)
  • JWT secrets
  • Email credentials
  • OAuth client secrets
  • Encryption keys
  • Service URLs

Can hardcode (non-secret config):

  • API route paths (e.g., /api/v1/feed)
  • Pagination defaults (e.g., page size 10)
  • Validation rules (e.g., min password length 8)
  • Error messages
  • HTTP status codes

Practical Example: DevTinder

# .env.development NODE_ENV=development PORT=3000 MONGODB_URI=mongodb://localhost:27017/devtinder_dev JWT_SECRET=dev_secret_not_for_production_abc123 CLIENT_URL=http://localhost:5173 ENABLE_EMAILS=false LOG_LEVEL=debug
# .env.production NODE_ENV=production PORT=3000 MONGODB_URI=mongodb+srv://prod:[email protected]/devtinder_prod JWT_SECRET=prod_secret_64_char_random_hex_string CLIENT_URL=https://app.yourdomain.com ENABLE_EMAILS=true LOG_LEVEL=warn

Same code, different behavior just by changing .env.

The Takeaway

Never hardcode secrets or environment-specific config in your code. Use environment variables for everything that changes between environments (database URIs, API keys, secrets, URLs, feature flags). Hardcode only logic that's the same everywhere (route paths, validation rules, error messages). This follows the 12-factor app methodology and keeps your code secure, flexible, and portable.

Hardcoded secrets are committed to Git history forever (even after deletion), visible to all team members, same across all environments (dev and prod share secrets), can't be changed without code modification, and are a serious security risk. Use environment variables instead.

Factor 3 states that config should be stored in environment variables, not in code. Code is logic (same across all environments). Config is variables that change between environments (database URIs, API keys, secrets). Separating them makes your app secure, flexible, and portable.

Use env vars for: database URIs, API keys, JWT secrets, email credentials, service URLs, feature flags, logging levels. Hardcode: API route paths, pagination defaults, validation rules, error messages, HTTP status codes anything that's the same in all environments and not a secret.

You use the same code with different .env files for each environment. .env.development has local DB and dev secrets. .env.production has production DB and strong secrets. No code changes needed just swap the .env file. This makes deployment easy and secure.

Security (secrets not in Git), flexibility (change config without code changes), multiple environments (different .env per env), team-friendly (each developer has own .env), and easy deployment (same code, different .env). This is the industry standard for Node.js configuration.

Ready to master Node.js completely?

Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course to dive deeper with high-quality video tutorials, solve interview questions, and a premium community.

Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.