For AI agents: a documentation index is available at https://www.mongodb.com/docs/llms.txt — markdown versions of all pages are available by appending .md to any URL path.
Docs Menu

Integrate MongoDB with React

In this guide, you can learn how to create a React web application that uses the MERN stack. The MERN stack is a web development framework that uses MongoDB, Express, React, and Node.js and consists of the following layers:

  • Database layer: MongoDB provides data storage and retrieval.

  • Application layer: Express and Node.js make up the middle tier for server-side logic.

  • Presentation layer: React implements the user interface and client-side interactions.

By storing your React application data in MongoDB, you can use the document data model to build complex query expressions. The document model's flexibility allows you to store nested data structures and iterate quickly on your application design. You can also grow your application by using the horizontal scaling capabilities in MongoDB.

The MERN stack with MongoDB supports applications that require dynamic, evolving data structures. As a result, this framework is well-designed for real world applications such as real-time dashboards or one-page applications that update content continuously.

This tutorial shows you how to build a web application by using the MERN stack. The application accesses sample restaurant data, queries the data, and displays the results on a locally hosted site. The tutorial also includes instructions for connecting to a MongoDB cluster hosted on MongoDB Atlas and accessing and displaying data from your database.

Tip

If you prefer to connect to MongoDB by using the Node.js driver without React, see the Get Started with the Node.js Driver guide.

Follow the steps in this section to install the project dependencies, create an Atlas cluster, and set up the application directories.

1

To create the Quick Start application, you need the following software installed in your development environment:

Prerequisite
Notes

Download either the Latest LTS or Latest Release version.

Code editor

This tutorial uses Visual Studio Code, but you can use the editor of your choice.

Terminal app and shell

For MacOS users, use Terminal or a similar app. For Windows users, use PowerShell.

2

MongoDB Atlas is a fully managed cloud database service that hosts your MongoDB deployments. If you do not have a MongoDB deployment, you can create a MongoDB cluster for free (no credit card required) by completing the MongoDB Get Started tutorial. The MongoDB Get Started tutorial also demonstrates how to load sample datasets into your cluster, including the sample_restaurants database that is used in this tutorial.

To connect to your MongoDB cluster, you must use a connection URI. To learn how to retrieve your connection URI, see the Add your connection string section of the MongoDB Get Started tutorial.

Important

Save your connection string in a secure location.

3

Run the following command in your terminal to create a directory for your project named react-quickstart:

mkdir react-quickstart
cd react-quickstart

Then, run the following commands from the react-quickstart directory to create a folder for the back end named server and initialize the package.json file:

mkdir server
cd server
npm init -y
4

Navigate to the package.json file in the react-quickstart/server directory. To use ECMAScript modules, the standard format for packaging JavaScript code for reuse, replace the existing line that specifies the "type" field with the following line:

"type": "module",

Run the following command to install the mongodb, express, and cors dependencies:

npm install mongodb express cors

This command installs MongoDB, the Express web framework, and the cors Node.js package that enables cross-origin resource sharing.

After setting up the project structure and dependencies, follow the steps in this section to configure your web server and connect to MongoDB.

1

Run the following command from the react-quickstart/server directory to create a file named server.js:

touch server.js
New-Item -ItemType File server.js

Paste the following code into the file:

react-quickstart/server/server.js
import express from "express";
import cors from "cors";
import restaurants from "./routes/restaurant.js";
const PORT = process.env.PORT || 5050;
const app = express();
app.use(cors());
app.use(express.json());
app.use("/restaurant", restaurants);
// start the Express server
app.listen(PORT, () => {
console.log(`Server listening on port ${PORT}`);
});

This file is the entry point for your back end. It starts an Express server, enables Cross-Origin Resource Sharing (CORS) so that your React client can call the server, and mounts the routes defined in routes/restaurant.js at the /restaurant path. You create the routes/restaurant.js file in a later step.

2

Run the following command from the server directory to create a file named config.env:

touch config.env
New-Item -ItemType File config.env

Add the following variables to the file:

MONGODB_URI=<connection URI>
PORT=5050

Replace the <connection URI> placeholder with the connection URI that you saved in a previous step.

3

Run the following commands from the server directory to create a new folder named db that contains a connection.js file:

mkdir db
touch db/connection.js
mkdir db
New-Item -ItemType File db/connection.js

Paste the following code into the connection.js file:

import { MongoClient } from "mongodb";
const uri = process.env.MONGODB_URI || "";
const client = new MongoClient(uri);
try {
// Connect the client to the server
await client.connect();
// Send a ping to confirm a successful connection
await client.db("admin").command({ ping: 1 });
console.log(
"Pinged your deployment. You successfully connected to MongoDB!"
);
} catch(err) {
console.error(err);
}
let db = client.db("sample_restaurants");
export default db;

This file connects to your MongoDB deployment, accesses the sample_restaurants database, and tests the database connection. It exports the database connection as db. In the next step, the routes/restaurant.js file imports this db connection from ../db/connection.js to query the database.

4

Run the following commands from the server directory to create a new folder named routes that contains a restaurant.js file:

mkdir routes
touch routes/restaurant.js
mkdir routes
New-Item -ItemType File routes/restaurant.js

Paste the following code into the restaurant.js file:

react-quickstart/server/routes/restaurant.js
import express from "express";
import db from "../db/connection.js";
// Creates an instance of the Express router, used to define our routes
const router = express.Router();
// Gets a list of all the restaurants
router.get("/", async (req, res) => {
let collection = await db.collection("restaurants");
let results = await collection.find({}).toArray();
res.send(results).status(200);
});
// Lists restaurants that match the query filter
router.get("/browse", async (req, res) => {
try {
let collection = await db.collection("restaurants");
let query = {
borough: "Queens",
name: { $regex: "Moon", $options: "i" },
};
let results = await collection.find(query).toArray();
res.send(results).status(200);
} catch (err) {
console.error(err);
res.status(500).send("Error browsing restaurants");
}
});
export default router;

This file imports the db connection from db/connection.js, accesses the restaurants collection in the sample_restaurants database, and defines the following GET endpoints:

  • /: Retrieves all restaurants from the sample collection

  • /browse: Retrieves restaurants that match the query criteria, which filters for restaurants in Queens that contain the word "Moon" in the name

After setting up the application's server, follow the steps in this section to configure React and add the client components.

1

Navigate to the react-quickstart directory. Then, run the following command to add the React template files by using Vite:

npm create vite@latest client

This command prompts you to respond to a series of configuration questions. For each question, choose the following responses from the dropdown menu:

  • Select a framework: React

  • Select a variant: JavaScript

  • Use rolldown-vite (Experimental)?: No

  • Install with npm and start now?: No

After running the command, your project has a client directory that contains client-side scaffolding.

2

This sample application uses the Tailwind CSS framework for UI formatting. Navigate to the client directory, then run the following command to install Tailwind CSS:

npm install tailwindcss @tailwindcss/vite

After installing, navigate to your vite.config.js file. Add the @tailwindcss/vite plugin by updating the import statements and plugins array, as shown in the highlighted lines:

react-quickstart/client/vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
// https://vite.dev/config/
export default defineConfig({
plugins: [
react(),
tailwindcss()
],
})

Then, replace the contents of the client/src/index.css file with the following import statement:

@import "tailwindcss";
3

To enable client-side page routing to React, install the react-router-dom package by running the following command in the client directory:

npm install react-router-dom
4

Navigate to the client/src/main.jsx file and paste the following code:

react-quickstart/client/src/main.jsx
import * as React from "react";
import * as ReactDOM from "react-dom/client";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import App from "./App";
import RestaurantList from "./components/RestaurantList";
import "./index.css";
const router = createBrowserRouter([
{
path: "/",
element: <App />,
children: [
{
path: "/",
element: <RestaurantList />,
},
],
},
{
path: "/browse",
element: <App />,
children: [
{
path: "/browse",
element: <RestaurantList />,
},
],
},
]);
ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode>
<RouterProvider router={router} />
</React.StrictMode>,
);

This file is the entry point for your client. It imports the App layout component and the RestaurantList component, configures client-side routing, and defines the following routes:

  • /: Renders the RestaurantList component, which calls the /restaurant/ API endpoint to display all restaurants

  • /browse: Renders the RestaurantList component, which calls the /restaurant/browse API endpoint to display filtered restaurants

5

Run the following commands from the client directory to create a new folder named components that contains two files:

mkdir src/components
cd src/components
touch Navbar.jsx RestaurantList.jsx
mkdir src/components
cd src/components
New-Item -ItemType File Navbar.jsx
New-Item -ItemType File RestaurantList.jsx

The Navbar.jsx file configures a navigation bar that links to the required components. Paste the following code into this file:

react-quickstart/client/src/components/Navbar.jsx
import { NavLink } from "react-router-dom";
export default function Navbar() {
return (
<div>
<nav className="flex justify-between items-center mb-6">
<NavLink to="/">
<img
alt="MongoDB logo"
className="h-10 inline"
src="https://d3cy9zhslanhfa.cloudfront.net/media/3800C044-6298-4575-A05D5C6B7623EE37/4B45D0EC-3482-4759-82DA37D8EA07D229/webimage-8A27671A-8A53-45DC-89D7BF8537F15A0D.png"
></img>
</NavLink>
</nav>
</div>
);
}

The RestaurantList.jsx file is the viewing component for the restaurants, and it retrieves and displays the restaurant information. It sends requests to the /restaurant API endpoints defined in server/routes/restaurant.js. Paste the following code into this file:

react-quickstart/client/src/components/RestaurantList.jsx
import { useEffect, useState } from "react";
import { useLocation } from "react-router-dom";
const Restaurant = (props) => (
<tr className="border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted">
<td className="p-4 align-middle [&:has([role=checkbox])]:pr-0">
{props.restaurant.name}
</td>
<td className="p-4 align-middle [&:has([role=checkbox])]:pr-0">
{props.restaurant.borough}
</td>
<td className="p-4 align-middle [&:has([role=checkbox])]:pr-0">
{props.restaurant.cuisine}
</td>
</tr>
);
export default function RestaurantList() {
const [restaurants, setRestaurants] = useState([]);
const location = useLocation();
// Fetches the restaurants from the database
useEffect(() => {
async function getRestaurants() {
// Determines which endpoint to call based on current route
const endpoint =
location.pathname === "/browse"
? "http://localhost:5050/restaurant/browse"
: "http://localhost:5050/restaurant/";
const response = await fetch(endpoint);
if (!response.ok) {
const message = `An error occurred: ${response.statusText}`;
console.error(message);
return;
}
const restaurants = await response.json();
setRestaurants(restaurants);
}
getRestaurants();
return;
}, [location.pathname]);
// Maps each restaurant on the table
function restaurantList() {
return restaurants.map((restaurant) => {
return <Restaurant restaurant={restaurant} key={restaurant._id} />;
});
}
// Retrieves the dynamic title based on current route
const getTitle = () => {
return location.pathname === "/browse"
? 'Filtered Restaurants (Queens, containing "Moon")'
: "All Restaurants";
};
// Displays the restaurants table
return (
<>
<h3 className="text-lg font-semibold p-4">{getTitle()}</h3>
<div className="border rounded-lg overflow-hidden">
<div className="relative w-full overflow-auto">
<table className="w-full caption-bottom text-sm">
<thead className="[&_tr]:border-b">
<tr className="border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted">
<th className="h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0">
Name
</th>
<th className="h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0">
Borough
</th>
<th className="h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0">
Cuisine
</th>
</tr>
</thead>
<tbody className="[&_tr:last-child]:border-0">
{restaurantList()}
</tbody>
</table>
</div>
</div>
</>
);
}

Finally, navigate to the client/src/App.jsx file. This file is the main layout component, and it ensures that the Navbar component renders at the top of each page above the child component. Paste the following code into this file:

react-quickstart/client/src/App.jsx
import { Outlet } from "react-router-dom";
import Navbar from "./components/Navbar";
const App = () => {
return (
<div className="w-full p-6">
<Navbar />
<Outlet />
</div>
);
};
export default App;

Finally, follow the steps in this section to run your application and view the rendered restaurant data.

1

Navigate to the react-quickstart/server directory and run the following command to start the server:

node --env-file=config.env server

If successful, this command outputs the following information:

Pinged your deployment. You successfully connected to MongoDB!
Server listening on port 5050
2

In a separate terminal window, navigate to the react-quickstart/client directory. Run the following command to start the React client:

npm run dev

If successful, this command outputs the following information:

VITE v7.2.4 ready in 298 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
➜ press h + enter to show help
3

Open the http://localhost:5173/ URL, retrieved from the preceding step. The initial landing page displays a list all restaurants in the sample_restaurants.restaurants collection:

The landing page that displays all restaurants

Then, navigate to the http://localhost:5173/browse URL to view the restaurants that match the name and borough field query:

The web page that displays the matching restaurants

Congratulations on completing the Quick Start tutorial!

After you complete these steps, you have a React web application that connects to your MongoDB deployment, runs a query on sample restaurant data, and renders a retrieved result.

If you encounter issues while completing this tutorial, review the following common problems and solutions.

If the server terminal prints a connection error instead of the Pinged your deployment. message, verify the following:

  • The MONGODB_URI value in your config.env file matches the connection string from Atlas and includes your database username and password.

  • You loaded the sample_restaurants dataset into your cluster.

If your browser console shows a CORS error when the client requests data, confirm that your server.js file calls app.use(cors()) before the route definitions.

If the web page loads but no restaurants appear, confirm that both the server and the client are running at the same time in separate terminal windows. The React client fetches data from the server at http://localhost:5050, so the server must be running for data to display.

If the server fails to start because port 5050 is already in use, change the PORT value in your config.env file. If you change the server port, update the endpoint URLs in RestaurantList.jsx to match. If the client port 5173 is in use, Vite automatically selects the next available port and prints the URL in the terminal.

To learn more about React, MongoDB, and the MERN stack, view the following resources: