DEV Community

Cover image for Database Connection in Next.js using Mongoose 📓⚡
Himanay Khajuria
Himanay Khajuria

Posted on

Database Connection in Next.js using Mongoose 📓⚡

When we build a web application, we usually need a place to store data. This data can be users, blog posts, images or comments. For this we use a database.

In many Next.js projects, developers use MongoDB as the database and Mongoose as the tool to connect with it.

In this blog we will learn how to create a database connection in Next.js using a simple example.


🍃 What is MongoDB

MongoDB is a NoSQL database. It stores data in a flexible format called documents.

These documents look very similar to JavaScript objects, which makes it easy to work with JavaScript frameworks like Next.js.

✨ Example

{
  name: "Himanay",
  role: "Frontend Developer",
  country: "Sweden"
}
Enter fullscreen mode Exit fullscreen mode

Because the structure looks like a JavaScript object, developers can easily read, update and manage data.


🧠 What is Mongoose

Mongoose is a library that helps Node.js connect with MongoDB. It also helps manage database data easily.

👉 Mongoose helps us to

  • Connect to the database
  • Create models
  • Read data
  • Write data
  • Update and delete data

📦 Install Mongoose

Run this command in your project

npm install mongoose
Enter fullscreen mode Exit fullscreen mode

📁 Step 1 Create Database Connection File

In a Next.js project, we usually create a file called db.ts.

This file handles the database connection so it can be reused in different parts of the application.

📌 Example db.ts

import mongoose from "mongoose";

const MONGODB_URI = process.env.MONGODB_URI!;

if (!MONGODB_URI) {
    throw new Error("Please define mongodb uri in env file");
}

let cached = global.mongoose;

if(!cached){
    cached = global.mongoose = {conn: null, promise: null};
}

export async function connectToDatabase(){
    if(cached.conn){
        return cached.conn;
    }

    if (!cached.promise) {
      const opts = {
        bufferCommands: true,
        maxPoolSize: 10,
      };

      cached.promise = mongoose
        .connect(MONGODB_URI, opts)
        .then(() => mongoose.connection);
    }

    try {
        cached.conn = await cached.promise;
    } catch (error) {
        cached.promise = null;
        throw error;
    }

    return cached.conn;
}
Enter fullscreen mode Exit fullscreen mode

📋 Understanding the Code Step by Step

1️⃣ Import Mongoose

First we import mongoose so we can connect to MongoDB.

import mongoose from "mongoose";
Enter fullscreen mode Exit fullscreen mode

2️⃣ Read the MongoDB Connection URL

Next we read the MongoDB URI from environment variables.

const MONGODB_URI = process.env.MONGODB_URI!;
Enter fullscreen mode Exit fullscreen mode

📄 Example .env.local

MONGODB_URI=mongodb+srv://username:password@cluster.mongodb.net/blogdb
Enter fullscreen mode Exit fullscreen mode

✔ This keeps database credentials secure.


3️⃣ Check if the URI exists

If the MongoDB URI is missing the application will throw an error.

if (!MONGODB_URI) {
    throw new Error("Please define mongodb uri in env file");
}
Enter fullscreen mode Exit fullscreen mode

This prevents the app from running with a missing database configuration.


4️⃣ Create a Cached Connection

Next we create a cached connection.

This is important because Next.js reloads the server many times during development.

let cached = global.mongoose;
Enter fullscreen mode Exit fullscreen mode

If the connection does not exist we initialize it.

if(!cached){
    cached = global.mongoose = {conn: null, promise: null};
}
Enter fullscreen mode Exit fullscreen mode

📦 This object stores

  • conn → active database connection
  • promise → pending database connection

This helps reuse the connection instead of creating new ones repeatedly.


5️⃣ Create the Database Connection

Now we create the actual connection.

cached.promise = mongoose
  .connect(MONGODB_URI, opts)
  .then(() => mongoose.connection);
Enter fullscreen mode Exit fullscreen mode

⚙️ Options used

  • bufferCommands: true

    • queues commands before the connection is ready
  • maxPoolSize: 10

    • limits the number of database connections

6️⃣ Save the Connection

Once the connection is ready we store it.

cached.conn = await cached.promise;
Enter fullscreen mode Exit fullscreen mode

Now the application will reuse the same connection instead of creating a new one.


7️⃣ Return the Database Connection

Finally the function returns the connection.

return cached.conn;
Enter fullscreen mode Exit fullscreen mode

This allows other parts of the application to use the database.


🧩 TypeScript Global Types File

Next we create a file called types.d.ts.

This helps TypeScript understand the global mongoose variable.

Example

import { Connection } from "mongoose"

declare global {
    var mongoose: {
        conn: Connection | null
        promise: Promise<Connection> | null
    }
}

export {};
Enter fullscreen mode Exit fullscreen mode

✔ This prevents TypeScript errors and defines the structure of the cached object.


🔌 How to Use the Connection

Now we can use the connection anywhere in the project.

Example in an API route

import { connectToDatabase } from "@/lib/db";

export async function GET() {

  await connectToDatabase();

  return Response.json({
    message: "Database connected successfully"
  });

}
Enter fullscreen mode Exit fullscreen mode

When the API runs

  1. Connect to MongoDB
  2. Reuse existing connection if available
  3. Return the API response

📝 Example in a Blog Project

Imagine we are building a blog platform.

A blog document in MongoDB may look like this

{
  title: "Learning Next.js",
  content: "Database connection in Nextjs blog",
  author: "Himanay"
}
Enter fullscreen mode Exit fullscreen mode

Using the database connection, we can

  • Save blog posts
  • Fetch blog posts
  • Update blog posts
  • Delete blog posts

Why Connection Caching is Important

❌ Without caching

  • Many database connections open
  • Database becomes slow
  • Server may crash

✅ With caching

  • One connection reused
  • Faster API requests
  • Better performance

📚 Summary

In this blog we learned

  • What MongoDB is
  • What Mongoose does
  • How to create a database connection in Next.js
  • Why caching connections is important
  • How TypeScript global types help

This setup is commonly used in modern Next.js full stack projects.

The database can store

  • 👤 Users
  • 📝 Blog posts
  • 🖼 Image metadata

🚀 Final Thought

Learning how to create a database connection is one of the first steps in building a full stack Next.js application.

Once the connection works correctly you can start building authentication, blog systems, dashboards and APIs.

Keep learning and keep building projects 💻

Top comments (0)