Mastering Environment Variables in Node.js with dotenv
Stop hardcoding database credentials and API keys. Learn how to use dotenv to secure your Node.js application configuration with environment variables.

Previously in this course, we explored The OS and Process Modules, where we first encountered process.env. In that lesson, we learned that Node.js can read system-level variables, but relying on the operating system alone is brittle and difficult for local development.
Today, we are taking a crucial step in our project: moving our hardcoded database connection strings and secret keys into a dedicated configuration file using dotenv. This is a professional standard that keeps your credentials out of version control and allows your app to behave differently in development, testing, and production.
Why Use Environment Variables?
Hardcoding credentials like MONGO_URI='mongodb://localhost:27017/myapp' is a dangerous anti-pattern. If you push that code to a repository (like GitHub), anyone with access can compromise your database.
Environment variables allow us to:
- Decouple configuration from code: Your logic stays the same; only the settings change.
- Improve Security: Secrets never touch your Git history.
- Simplify Deployment: You can inject different values (like a production database URL) on platforms like Render without changing your source code.
Getting Started with dotenv

The dotenv package is the industry standard for loading variables from a .env file into process.env.
1. Installation
In your project directory, install the package:
Bashnpm install dotenv
2. Creating the .env File
At the root of your project, create a file named .env. This file should never be committed to Git. Add your configuration values in KEY=VALUE format:
TEXT# .env file PORT=3000 DB_URI=mongodb://localhost:27017/my-rest-api JWT_SECRET=supersecretkey123
3. Loading Variables
You must load dotenv as early as possible in your application. In your main entry file (e.g., index.js or app.js), add this at the very top:
JAVASCRIPTrequire(CE9178">'dotenv').config(); const express = require(CE9178">'express'); const app = express(); // Now you can access your variables via process.env const port = process.env.PORT || 8080; const dbUri = process.env.DB_URI; console.log(CE9178">`Server starting on port ${port}`);
Worked Example: Connecting to MongoDB
We previously learned about Connecting to MongoDB with Mongoose. Let’s refactor that connection to use our new environment variable:
JAVASCRIPT// config/db.js const mongoose = require(CE9178">'mongoose'); const connectDB = async () => { try { // We access the variable defined in our .env file await mongoose.connect(process.env.DB_URI); console.log(CE9178">'MongoDB Connected...'); } catch (err) { console.error(err.message); process.exit(1); } }; module.exports = connectDB;
Practice Exercise
- Add a new variable called
NODE_ENVto your.envfile and set it todevelopment. - In your main server file, add a condition: if
process.env.NODE_ENV === 'development', log "Running in development mode" to the console. - Crucial: Add
.envto your.gitignorefile immediately to ensure you don't accidentally leak your secrets.
Common Pitfalls

- Committing the .env file: Always add
.envto.gitignore. If you accidentally commit it, you must rotate your keys immediately, as they are now public. - Late loading: If you attempt to access
process.env.DB_URIbefore callingrequire('dotenv').config(), the value will beundefined. - Missing Variables: If your application crashes because a variable is missing, implement a check at startup to ensure required environment variables are present, rather than letting the app fail silently later.
FAQ
Q: Can I use different .env files for different environments?
A: Yes, though usually you define standard variables in .env and let your hosting provider (like Render or Heroku) override them via their dashboard interface.
Q: Should I put non-sensitive config in .env?
A: It is a matter of preference, but many teams keep all "environment-specific" settings in .env to maintain a single source of truth for configuration.
Q: How do I share my .env file with teammates?
A: Create a file called .env.example. This file contains the keys (e.g., DB_URI=) but no real values. Commit this to your repo so others know which variables they need to define locally.
Recap

By using dotenv, we've successfully decoupled our configuration from our source code. We've moved from hardcoded strings to a secure, environment-aware setup. This practice is essential for building production-ready APIs, similar to the techniques discussed in Using Environment Variables in Next.js: A Security Guide or Environment Variables: A Developer’s Guide to Shell Configuration.
Up next: We will learn how to verify our API endpoints reliably using Postman.
Work with me

Laravel REST API Development
Clean, secure, well-documented Laravel REST APIs — the backend engine for your app, mobile client, or SaaS. Built by an API specialist.

FilamentPHP Admin Panel & Dashboard Development
A powerful admin panel for your Laravel app — built with FilamentPHP so you can manage everything without touching the database.


