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:
- Node.js — version 16.20.1 or later is recommended by MongoDB’s current Node.js driver documentation.
- 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.
- 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
Exposing Your Database Password
Never commit your .env file to GitHub.
Always add this to .gitignore:
".env"Forgetting express.json()
Without this middleware, Express cannot read JSON request bodies:
app.use(express.json());
- Using the Wrong Connection String Make sure you copied the Node.js driver connection string from MongoDB Atlas, not another language’s connection string.
- 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.