DEV Community

Cover image for Connect a React App with MongoDB using Node.js and Express.js
Sudhanshu Gaikwad
Sudhanshu Gaikwad

Posted on

Connect a React App with MongoDB using Node.js and Express.js

Unlock the full potential of the MERN stack with this complete, beginner-to-pro guide! In this hands-on tutorial, you'll learn how to seamlessly connect your React.js frontend to a MongoDB database using Node.js and Express.js in 2025. We cover everything step-by-stepβ€”from setting up the backend server and creating RESTful APIs to integrating them into your React application.


πŸ“ Folder Structure

project-root/ β”‚ β”œβ”€β”€ backend/ β”‚ β”œβ”€β”€ config/ β”‚ β”‚ └── db.js β”‚ β”œβ”€β”€ models/ β”‚ β”‚ └── Note.js β”‚ β”œβ”€β”€ routes/ β”‚ β”‚ └── notes.js β”‚ β”œβ”€β”€ server.js β”‚ β”œβ”€β”€ frontend/ β”‚ β”œβ”€β”€ src/ β”‚ β”‚ β”œβ”€β”€ components/ β”‚ β”‚ └── App.js 
Enter fullscreen mode Exit fullscreen mode

Image description

Setup the Backend with Node.js, Express & MongoDB

mkdir backend cd backend npm init -y npm install express mongoose cors dotenv 
Enter fullscreen mode Exit fullscreen mode

Create MongoDB Connection File (config/db.js)

const mongoose = require("mongoose"); const connectDB = async (url) => { try { await mongoose.connect(url); // βœ… Clean usage console.log("βœ… MongoDB Connected"); } catch (error) { console.error("❌ MongoDB connection error:", error.message); process.exit(1); } }; module.exports = connectDB; 
Enter fullscreen mode Exit fullscreen mode

Define a Mongoose Model (models/Note.js)

const express = require("express"); const router = express.Router(); const Note = require("../models/Note"); router.get("/", async (req, res) => { const notes = await Note.find(); res.json(notes); }); router.post("/", async (req, res) => { const note = new Note(req.body); await note.save(); res.status(201).json(note); }); module.exports = router; 
Enter fullscreen mode Exit fullscreen mode

Create API Routes (routes/notes.js)

const express = require("express"); const router = express.Router(); const Note = require("../models/Note"); router.get("/", async (req, res) => { const notes = await Note.find(); res.json(notes); }); router.post("/", async (req, res) => { const note = new Note(req.body); await note.save(); res.status(201).json(note); }); module.exports = router; 
Enter fullscreen mode Exit fullscreen mode

Create server.js (Entry Point)

const express = require("express"); const cors = require("cors"); const dotenv = require("dotenv"); // βœ… Required for env support const connectDB = require("./config/db"); const notesRoutes = require("./routes/notes"); dotenv.config(); // βœ… Load .env variables const app = express(); const connection_url = "Enter your URL"; // βœ… Pass your connection URL to the connectDB function connectDB(connection_url); app.use(cors()); app.use(express.json()); app.use("/api/notes", notesRoutes); const PORT = process.env.PORT || 5000; app.listen(PORT, () => console.log(`πŸš€ Server running on port ${PORT}`)); 
Enter fullscreen mode Exit fullscreen mode

Setup Frontend with React

npx create-react-app frontend cd frontend npm install axios 
Enter fullscreen mode Exit fullscreen mode

Connect Frontend to Backend

import React, { useEffect, useState } from "react"; import axios from "axios"; import styled from "styled-components"; import { FaEdit, FaTrash } from "react-icons/fa"; // React Icons // Styled Components const Container = styled.div` max-width: 800px; margin: auto; padding: 1rem; font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; color: #fff; /* background: linear-gradient(145deg, #0d0d0d, #1a1a1a); */ min-height: 100vh; `; const Title = styled.h1` text-align: center; color: #00aaff; `; const Form = styled.div` display: flex; flex-direction: column; gap: 1rem; margin-bottom: 2rem; `; const Input = styled.input` padding: 0.75rem; font-size: 1rem; border: none; border-radius: 8px; background: transparent; border: 1px solid #353535; color: white; &:focus { border-color: #3f51ff; outline: none; } `; const TextArea = styled.textarea` padding: 0.75rem; font-size: 1rem; border: none; border-radius: 8px; background: transparent; border: 1px solid #353535; color: white; resize: vertical; &:focus { border-color: #3f51ff; outline: none; } `; const Button = styled.button` padding: 0.75rem; font-size: 1rem; background: #194bfd; background: linear-gradient( 90deg, rgba(25, 75, 253, 1) 0%, rgba(173, 19, 251, 1) 100% ); transition: all 0.3s ease; color: #ffffff; border: none; border-radius: 8px; cursor: pointer; &:hover { background-color: #5a189a; box-shadow: 0 6px 16px rgba(90, 24, 154, 0.5); color: #ffffff; transform: translateY(-2px); } `; const NoteGrid = styled.div` display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1.5rem; `; const NoteCard = styled.div` background: #1e1e1e; border-radius: 12px; padding: 1.5rem; position: relative; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.4); h3 { margin-top: 0; color: #00aaff; } p { color: #ccc; } .actions { margin-top: 1rem; display: flex; gap: 0.5rem; button { flex: 1; padding: 0.5rem; border: none; border-radius: 6px; cursor: pointer; font-weight: 500; display: flex; align-items: center; justify-content: center; gap: 5px; } .edit { background-color: #ffaa00; color: #121212; &:hover { background-color: #e69a00; } } .delete { background-color: #ff4d4d; color: white; &:hover { background-color: #e04343; } } } `; function App() { const [notes, setNotes] = useState([]); const [form, setForm] = useState({ title: "", content: "" }); const [editingId, setEditingId] = useState(null); const fetchNotes = async () => { const res = await axios.get("http://localhost:5000/api/notes"); setNotes(res.data); }; const addOrUpdateNote = async () => { if (editingId) { await axios.put(`http://localhost:5000/api/notes/${editingId}`, form); setEditingId(null); } else { await axios.post("http://localhost:5000/api/notes", form); } fetchNotes(); setForm({ title: "", content: "" }); }; const deleteNote = async (id) => { await axios.delete(`http://localhost:5000/api/notes/${id}`); fetchNotes(); }; const editNote = (note) => { setForm({ title: note.title, content: note.content }); setEditingId(note._id); }; useEffect(() => { fetchNotes(); }, []); return ( <Container> <Title>πŸ“ Notes App</Title>  <Form> <Input type="text" placeholder="Title" value={form.title} onChange={(e) => setForm({ ...form, title: e.target.value })} />  <TextArea placeholder="Content" rows={4} value={form.content} onChange={(e) => setForm({ ...form, content: e.target.value })} />  <Button onClick={addOrUpdateNote}> {editingId ? "Update Note" : "Add Note"} </Button>  </Form>  <h2 style={{ color: "#ccc" }}>All Notes</h2>  <NoteGrid> {notes.map((note) => ( <NoteCard key={note._id}> <h3>{note.title}</h3>  <p>{note.content}</p>  <div className="actions"> <button className="edit" onClick={() => editNote(note)}> <FaEdit /> Edit </button>  <button className="delete" onClick={() => deleteNote(note._id)}> <FaTrash /> Delete </button>  </div>  </NoteCard>  ))} </NoteGrid>  </Container>  ); } export default App; 
Enter fullscreen mode Exit fullscreen mode

Final Steps

Run backend:

node server.js 
Enter fullscreen mode Exit fullscreen mode

Run frontend:

npm start 
Enter fullscreen mode Exit fullscreen mode

Image description

Deploying to the Internet

  • Use Render or Railway for backend deployment
  • Use Vercel or Netlify for frontend deployment
  • Connect via environment variables and update frontend API URL

Conclusion

Congratulations! You've successfully built a full-stack MERN application by connecting a React frontend to a MongoDB database using Node.js and Express. From setting up the server and creating RESTful APIs to integrating them into your React componentsβ€”you've now covered all the essential steps needed to master the foundational flow of full-stack development.

Top comments (0)