Dev By Diwash
The Best Way to Connect MongoDB with Next.js Image

Spread it online!

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

  • connection is a singleton object that remembers if the connection is already established.
  • mongoose.connect() returns an object containing the connections array.
  • readyState tells whether the database is connected (1 = connected).
  • Event listeners provide logging and safety for connection errors.
  • Wrapped with async/await using 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-name

Common Pitfalls

  • Connecting to MongoDB on every request without checking existing connections.
  • Not using process.env.MONGODB_URI securely (make sure it's in your .env file).
  • Forgetting to set dbName in mongoose.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.