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

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

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)