The Best Way to Connect MongoDB with Next.js
When working with MongoDB in a Next.js project, especially one using the App Router, managing your database connections properly is crucial to prevent reconnections, stale connections, or memory leaks.
In this article, I'll show you the cleanest and most scalable way to connect MongoDB using Mongoose with support for promise-based handling, logging, and connection reuse.
Why We Need Connection Management
Every time a new request hits the server, Next.js may spin up a new Lambda function — and without proper connection checks, this can result in multiple unnecessary MongoDB connections.
This pattern ensures:
- One connection is reused across the app lifecycle
- Cleaner logs and error handling
- Full use of TypeScript and async/await
Final Code (Copy-Paste Ready)
In your /src/app/lib/connect-to-database.ts:
import mongoose from "mongoose";
type ConnectionType = {
isConnected?: number;
};
const connection: ConnectionType = {};
const connectToDatabase = async (): Promise<void> => {
if (connection.isConnected) {
console.log(`Already Connected to MongoDB Successfully`);
return;
}
try {
const { connections: dbConnection } = await mongoose.connect(
process.env.MONGODB_URI! as string,
{
dbName: process.env.MONGODB_NAME,
}
);
connection.isConnected = dbConnection[0].readyState;
mongoose.connection.on("connected", () =>
console.log("Connected to MongoDB Successfully")
);
mongoose.connection.on("error", (err) => {
console.log(`Mongodb connection error: ${err}`);
process.exit(1);
});
} catch (error) {
console.error("Error connecting to MongoDB", error);
process.exit(1);
}
};
export default connectToDatabase;How It Works
connectionis a singleton object that remembers if the connection is already established.mongoose.connect()returns an object containing theconnectionsarray.readyStatetells whether the database is connected (1= connected).- Event listeners provide logging and safety for connection errors.
- Wrapped with
async/awaitusing Promise to support async server functions in Next.js.
Usage
In your app/api/ routes or server components:
import { NextRequest, NextResponse } from "next/server";
import connectToDatabase from "@/lib/connect-to-database";
export async function GET(req: NextRequest) {
if (req.method !== "GET") {
return NextResponse.json(
{ error: "Method Not Allowed" },
{
status: 405,
}
);
}
await connectToDatabase();
// Your logic here
return NextResponse.json({ message: "Success" });
}Secure Your ENV
In your .env.local file:
MONGODB_URI=mongodb+srv://your-user:your-pass@cluster.mongodb.net
MONGODB_NAME=your-database-nameCommon Pitfalls
- Connecting to MongoDB on every request without checking existing connections.
- Not using
process.env.MONGODB_URIsecurely (make sure it's in your.envfile). - Forgetting to set
dbNameinmongoose.connect.
This setup gives you a clean, production-ready MongoDB connection pattern that's fully compatible with the latest Next.js App Router and server components.
