Learn how to connect Node.js to MongoDB, create a database, model data with Mongoose, and build a simple CRUD API — step by step.
MongoDB and Node.js are one of the most popular combinations for building modern backend applications. MongoDB stores data as flexible JSON-like documents, while Node.js lets you build fast JavaScript-powered servers. Together, they are a great starting point for full-stack development.
In this guide, you will set up MongoDB with Node.js from scratch and build a small Tasks API that can create, read, update, and delete tasks.

By the end, you will know how to:
1.Set up a Node.js project
2.Connect to MongoDB using Mongoose
3.Create a schema and model
4.Build CRUD endpoints with Express
5.Store credentials safely with environment variables
6.Avoid common beginner mistakes

MongoDB’s official Node.js driver supports connecting to MongoDB Atlas or a local MongoDB instance, and Mongoose is a widely used ODM that adds schemas, validation, and model-based data access on top of MongoDB.
Prerequisites
Before starting, install the following:

  1. Node.js — version 16.20.1 or later is recommended by MongoDB’s current Node.js driver documentation.
  2. npm — installed automatically with Node.js. 3.MongoDB Atlas account — the easiest free way to host a database in the cloud. 4.Code editor — VS Code is a good choice.
  3. Basic JavaScript knowledge — especially async/await, objects, and arrays. You do not need to install MongoDB locally for this tutorial. We will use MongoDB Atlas, MongoDB’s managed cloud database service.

What You Will Build
You will create a simple REST API for managing tasks.


Each task will contain:
{
"title": "Learn MongoDB",
"completed": false
}

Step 1: Create the Node.js Project
Open your terminal and run:
mkdir node-mongodb-tasks-api
cd node-mongodb-tasks-api
npm init -y

This creates a folder and a package.json file.
Now install the required dependencies:

npm install express mongoose dotenv
npm install -D nodemon

Here is what each package does:
1.express — creates the web server and API routes.
2.mongoose — connects Node.js to MongoDB and helps define data models.
3.dotenv — loads secret values from a .env file.
4.nodemon — automatically restarts the server when you change code.
Open package.json and update the scripts section:
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js"
}

You can now start your project in development mode with:

npm run dev

Step 2: Set Up MongoDB Atlas
MongoDB Atlas is a cloud-hosted MongoDB service. It is ideal for beginners because you do not need to configure a local database server.
1.Go to MongoDB Atlas.
2.Create a free account.
3.Create a free M0 cluster.
4.Create a database user with a username and password.
5.Add your current IP address to the network access list.
6.Click Connect.
7.Choose Drivers.
8.Select Node.js.
9.Copy the connection string.
MongoDB’s documentation recommends creating a database user, adding your IP address to the access list, and selecting the Node.js driver to obtain a connection string.
Your connection string will look similar to this:

mongodb+srv://:@cluster0.xxxxx.mongodb.net/?retryWrites=true&w=majority

Replace and with your actual database credentials.

Step 3: Store Secrets in a .env File
Never put your database password directly in your code.
Create a file named .env in your project root:
PORT=5000
MONGODB_URI=mongodb+srv://your_username:your_password@cluster0.xxxxx.mongodb.net/taskdb?retryWrites=true&w=majority

Create another file named .gitignore:
node_modules
.env
This prevents your secrets and dependencies from being uploaded to GitHub.

Step 4: Connect Node.js to MongoDB
Create a file named server.js:

import express from "express";
import mongoose from "mongoose";
import dotenv from "dotenv";

dotenv.config();

const app = express();

app.use(express.json());

const PORT = process.env.PORT || 5000;
const MONGODB_URI = process.env.MONGODB_URI;

mongoose
.connect(MONGODB_URI)
.then(() => {
console.log("Connected to MongoDB");

app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); }); 

})
.catch((error) => {
console.error("MongoDB connection failed:", error.message);
process.exit(1);
});

Add this to your package.json so Node.js can use modern import syntax:
"type": "module"
Now run:
npm run dev
If everything is correct, you should see:
Connected to MongoDB
Server running on port 5000

Mongoose’s official getting-started guide uses mongoose.connect() to open a connection to MongoDB, and MongoDB’s own Mongoose tutorial follows the same connection approach.

Step 5: Create a Mongoose Schema
A schema describes the structure of your data.
Create a folder called models, then create a file inside it called Task.js:

import mongoose from "mongoose";

const taskSchema = new mongoose.Schema(
{
title: {
type: String,
required: [true, "Task title is required"],
trim: true,
maxlength: [100, "Title cannot exceed 100 characters"]
},
completed: {
type: Boolean,
default: false
}
},
{
timestamps: true
}
);

const Task = mongoose.model("Task", taskSchema);

export default Task;

What This Does
1.title must be a string and is required.
2.completed defaults to false.
3.timestamps: true automatically adds createdAt and updatedAt fields.
4.mongoose.model() creates the Task model, which you will use to query the database.
Mongoose helps enforce a semi-rigid schema at the application level, which is useful when you want more structure and validation than raw MongoDB documents provide.

Step 6: Build the CRUD Routes
Create a folder named routes, then create a file called taskRoutes.js:
import express from "express";
import Task from "../models/Task.js";

const router = express.Router();

// Create a task
router.post("/", async (req, res) => {
try {
const task = await Task.create(req.body);
res.status(201).json(task);
} catch (error) {
res.status(400).json({ error: error.message });
}
});

// Get all tasks
router.get("/", async (req, res) => {
try {
const tasks = await Task.find().sort({ createdAt: -1 });
res.json(tasks);
} catch (error) {
res.status(500).json({ error: error.message });
}
});

// Get one task
router.get("/:id", async (req, res) => {
try {
const task = await Task.findById(req.params.id);

if (!task) { return res.status(404).json({ error: "Task not found" }); } res.json(task); 

} catch (error) {
res.status(400).json({ error: "Invalid task ID" });
}
});

// Update a task
router.put("/:id", async (req, res) => {
try {
const task = await Task.findByIdAndUpdate(req.params.id, req.body, {
new: true,
runValidators: true
});

if (!task) { return res.status(404).json({ error: "Task not found" }); } res.json(task); 

} catch (error) {
res.status(400).json({ error: error.message });
}
});

// Delete a task
router.delete("/:id", async (req, res) => {
try {
const task = await Task.findByIdAndDelete(req.params.id);

if (!task) { return res.status(404).json({ error: "Task not found" }); } res.json({ message: "Task deleted successfully" }); 

} catch (error) {
res.status(400).json({ error: "Invalid task ID" });
}
});

export default router;

Step 7: Connect Routes to the Server
Update server.js:
import express from "express";
import mongoose from "mongoose";
import dotenv from "dotenv";
import taskRoutes from "./routes/taskRoutes.js";

dotenv.config();

const app = express();

app.use(express.json());
app.use("/api/tasks", taskRoutes);

app.get("/", (req, res) => {
res.json({ message: "Welcome to the Task API" });
});

const PORT = process.env.PORT || 5000;
const MONGODB_URI = process.env.MONGODB_URI;

mongoose
.connect(MONGODB_URI)
.then(() => {
console.log("Connected to MongoDB");

app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); }); 

})
.catch((error) => {
console.error("MongoDB connection failed:", error.message);
process.exit(1);
});

Your project structure should now look like this:

node-mongodb-tasks-api/
├── models/
│ └── Task.js
├── routes/
│ └── taskRoutes.js
├── .env
├── .gitignore
├── package.json
└── server.js

Step 8: Test the API
npm run dev
You can test the API using Postman, Insomnia, or curl.
Create a Task
curl -X POST http://localhost:5000/api/tasks \
-H "Content-Type: application/json" \
-d '{"title":"Learn MongoDB with Node.js"
Expected response:
{
"id": "65f1a2b3c4d5e6f7a8b9c0d1",
"title": "Learn MongoDB with Node.js",
"completed": false,
"createdAt": "2026-11-03T13:00:00.000Z",
"updatedAt": "2026-11-03T13:00:00.000Z",
"
_v": 0
}

Get All Tasks
curl http://localhost:5000/api/tasks
Update a Task
curl -X PUT http://localhost:5000/api/tasks/YOUR_TASK_ID \
-H "Content-Type: application/json" \
-d '{"completed":true}'

Delete a Task
curl -X DELETE http://localhost:5000/api/tasks/YOUR_TASK_ID

Common Beginner Mistakes

  1. Exposing Your Database Password
    Never commit your .env file to GitHub.
    Always add this to .gitignore:
    ".env"

  2. Forgetting express.json()
    Without this middleware, Express cannot read JSON request bodies:

app.use(express.json());

  1. Using the Wrong Connection String Make sure you copied the Node.js driver connection string from MongoDB Atlas, not another language’s connection string.
  2. Not Handling Errors Database operations can fail. Always use try/catch around asynchronous MongoDB operations.

Next Steps
Once this works, try improving the project:
1.Add validation for empty titles.
2.Add filtering: GET /api/tasks?completed=true.
3.Add pagination using limit and skip.
4.Add user authentication with JWT.
5.Deploy the API to Render, Railway, or Vercel.
6.Connect it to a React frontend.
Final Project Code
Your complete server.js should look like this:
import express from "express";
import mongoose from "mongoose";
import dotenv from "dotenv";
import taskRoutes from "./routes/taskRoutes.js";

dotenv.config();

const app = express();

app.use(express.json());
app.use("/api/tasks", taskRoutes);

app.get("/", (req, res) => {
res.json({ message: "Welcome to the Task API" });
});

const PORT = process.env.PORT || 5000;
const MONGODB_URI = process.env.MONGODB_URI;

mongoose
.connect(MONGODB_URI)
.then(() => {
console.log("Connected to MongoDB");

app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); }); 

})
.catch((error) => {
console.error("MongoDB connection failed:", error.message);
process.exit(1);
});

Conclusion
You have now built a complete Node.js and MongoDB backend from scratch. You learned how to connect to MongoDB Atlas, define a Mongoose schema, create a model, and build a working CRUD API with Express.
This is a strong foundation for building real applications such as blogs, e-commerce platforms, task managers, and SaaS products.
If you found this helpful, follow me for more beginner-friendly Node.js, MongoDB, and backend development tutorials.