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)