How a Simple dotenv Mistake Turned My Express Server Setup into a Headache (And How You Can Avoid It)

Setting up an Express server is supposed to be straightforward, right? That’s what I thought too. As someone who’s been knee-deep in Docker-based development for a while, I decided to step outside my usual workflow to try out Google Social Login API on an Express server — without Docker this time.
I thought, “Why bother with Docker for a quick trial?” So, I went ahead and set up my project the old-fashioned way. I created a .env file and installed the dotenv package to manage environment variables. Everything seemed to be going smoothly.
Here’s what my app.ts looked like:
import express, { Express } from "express";
import cors from "cors";
import connectDb from "./services/connectDB";
import passport from "passport";
import routes from "./routes";
import bodyParser from "body-parser";
import session from "express-session";
const app: Express = express();
import dotenv from "dotenv";
dotenv.config();
console.log('MONGO_URI in app.ts', process.env.MONGODB_URI);
My .env file was set up like this:
MONGODB_URI=mongodb://localhost:27017
GOOGLE_CLIENT_SECRET=VERY_VERY_SECRET
GOOGLE_CLIENT_ID=VERY_SECRET
When I ran the server, the MONGODB_URI printed out just fine in app.ts. So far, so good, right?
Then, I moved on to my database connection logic in services/connectDB.ts:
import mongoose from "mongoose";
console.log("MONGODB_URI: ", process.env.MONGODB_URI);
const uri = process.env.MONGODB_URI || `mongodb://localhost:27017/test`;
const connectDb = async () => {
try {
console.log("Connecting String: ", uri);
await mongoose.connect(uri); // Connect to MongoDB
console.log("Connected to the database");
} catch (error) {
console.error(error);
}
};
export default connectDb;
To my surprise, the MONGODB_URI was undefined here. Confused, I added the dotenv import to this file, and suddenly everything worked as expected. But why was this happening? Why did I have to import dotenv in every file where I wanted to access my environment variables?
I went on a hunt through countless blogs, tried different approaches, but nothing clicked. Frustrated, I turned to ChatGPT, thinking, “Why not? Let’s see what it suggests.”
The solution?

A simple but critical change: import dotenv at the top of your main file, before anything else. Just like that, everything started working perfectly.
Here’s the updated app.ts:
import express, { Express } from "express";
// Updated CODE
import dotenv from "dotenv";
dotenv.config();
import cors from "cors";
import connectDb from "./services/connectDB";
import passport from "passport";
import routes from "./routes";
So, if you’re reading this because you’re tearing your hair out over dotenv not working in your Express app — stop searching and just move that dotenv import to the top of your main file.
Problem solved.