If you’re new to full-stack web development and want a hands-on project to practice React frontend integration with a + Express backend, this tutorial is for you. In this guide, we’ll walk through a simple but powerful app that lets users upload images, store them on the server, and display them back in the browser.
This project is based on my GitHub repo: . It’s designed to be beginner-friendly, SEO-optimized, and a great starting point for anyone learning JavaScript full-stack development.
🛠️ Technologies Used
Here’s the tech stack powering this project:
– JavaScript runtime for the backend.
– Lightweight web framework for building REST APIs.
Multer – Middleware for handling file uploads.
CORS – Enables cross-origin requests between frontend and backend.
– Frontend library for building user interfaces.
Vite – Fast development server and build tool for React.
Fetch API – For making HTTP requests from the frontend.
🎯 Intent of Building This Project
The goal of this project is to:
Teach beginners how to connect a React frontend with a backend.
Demonstrate how to handle file uploads using Multer.
Provide a starter template for building full-stack apps with REST APIs.
Show how to integrate frontend-backend communication without running into CORS issues.
⚙️ Backend Setup (Node.js + Express)
The backend provides REST API endpoints for uploading and retrieving images.
Install dependencies
npm install express multer cors
import express from "express";
import cors from "cors";
import multer from "multer";
const app = express();
const PORT = 3000;
// Enable CORS
app.use(cors());
// Configure Multer for file storage
const storage = multer.diskStorage({
destination: (req, file, cb) => cb(null, "uploads"),
filename: (req, file, cb) => cb(null, Date.now() + "-" + file.originalname),
});
const upload = multer({ storage });
// Simple test endpoint
app.get("/api/hello", (req, res) => {
res.json({ message: "Hello World!" });
});
// Upload endpoint
app.post("/api/upload", upload.single("file"), (req, res) => {
res.json({ file: req.file });
});
// List uploaded images
import fs from "fs";
app.get("/api/images", (req, res) => {
fs.readdir("uploads", (err, files) => {
if (err) return res.status(500).json({ error: err });
res.json({ images: files });
});
});
app.listen(PORT, () => console.log(`Backend running on http://localhost:${PORT}`));
🎨 Frontend Setup (React + Vite)
The frontend provides a simple UI for selecting and uploading files.
Install dependencies
npm create vite@latest frontend
cd frontend
npm install
import React, { useState } from "react";
function App() {
const [file, setFile] = useState(null);
const [message, setMessage] = useState("");
const handleUpload = async () => {
const formData = new FormData();
formData.append("file", file);
const response = await fetch("http://localhost:3000/api/upload", {
method: "POST",
body: formData,
});
const data = await response.json();
setMessage(`File uploaded: ${data.file.filename}`);
};
return (
<div>
<h1>React + Node.js File Upload</h1>
<input type="file" onChange={(e) => setFile(e.target.files[0])} />
<button onClick={handleUpload}>Upload</button>
<p>{message}</p>
</div>
);
}
export default App;
🔗 Connecting Frontend and Backend
To avoid CORS issues, configure Vite’s proxy in vite.config.js:
export default {
server: {
proxy: {
"/api": "http://localhost:3000",
},
},
};
This ensures that API calls from React (/api/...) are forwarded to the backend running on port 3000.
📸 Displaying Uploaded Images
You can extend the frontend to fetch and display uploaded images:
const [images, setImages] = useState([]);
const fetchImages = async () => {
const response = await fetch("/api/images");
const data = await response.json();
setImages(data.images);
};
useEffect(() => {
fetchImages();
}, []);
return (
<div>
<h2>Uploaded Images</h2>
{images.map((img, index) => (
<img key={index} src={`http://localhost:3000/uploads/${img}`} alt={img} />
))}
</div>
);
🧑💻 Why This Project Matters
Beginner-friendly: Perfect for those learning React + integration.
Practical use case: File uploads are common in real-world apps (profile pictures, documents, etc.).
Scalable foundation: You can extend this into a full photo gallery, cloud storage integration, or even an AI-powered image app.
✅ Conclusion
This project is a hands-on introduction to full-stack development using modern tools like React and Vite on the frontend, and + Express on the backend. By following this tutorial, you’ll learn how to handle file uploads, build REST APIs, and connect frontend and backend seamlessly.
👉 Check out the full repo here:
Comments