Show me: setting up a server
Express is the most popular package for building servers in Node.js – it turns the job into just a few lines. A server is a separate project, apart from the React app (remember: frontend and backend are two halves). In the terminal:
cd Desktop
mkdir my-server
cd my-server
npm init -y
npm install express
mkdircreates a folder (make directory),npm init -ysets up a new Node.js project (createspackage.json),npm install expressdownloads Express.
Open the folder in VS Code and create a file called server.js:
const express = require("express");
const app = express();
// When someone sends a GET to /api/hello, respond
app.get("/api/hello", (request, response) => {
response.json({ message: "Hi! This is your own server. 🎉" });
});
app.listen(3900, () => {
console.log("Server running at http://localhost:3900");
});
Run it:
node server.js
And open http://localhost:3900/api/hello in your browser. Do you see the JSON response? You just built a server. No magic – 10 lines.
What’s happening in the code:
require("express")– borrow a package (the server-side version ofimport).app.get("/api/hello", ...)– “respond to GET requests at this address.” That pair of address + response is called an endpoint.response.json({...})– send back JSON.app.listen(3900)– listen on port 3900. (Vite runs on 3901, the server on 3900 – two programs can’t listen on the same port.)
You stop the server with Ctrl+C. And watch out: after every code change, you have to stop and restart it – a server isn’t Vite, it doesn’t refresh itself.
Show me: a server with data
A server usually hands out data. Add a second endpoint above listen:
const results = [
{ opponent: "Lakeside", score: "3:1", home: true },
{ opponent: "Northgate", score: "2:2", home: false },
{ opponent: "Elmwood", score: "4:0", home: true },
];
app.get("/api/results", (request, response) => {
response.json(results);
});
Restart the server and open http://localhost:3900/api/results – your data, served through an API. This is exactly how every big website works (just with a database instead of an array).
Your turn 💪
- Get a server running by following the guide.
- Add an endpoint with data from your project: 🏫
/api/menu(an array of meals for the week) · 🙋/api/favorites(your top games/books) · 🌍/api/trips(a list of trips) · ⚽/api/results(match results). - Add a playful endpoint
/api/randomthat returns a different message every time:
const messages = ["We're winning today!", "Practice at 5 PM!", "Let's go, Eagles!"];
app.get("/api/random", (request, response) => {
const random = messages[Math.floor(Math.random() * messages.length)];
response.json({ message: random });
});
- Try out all the endpoints in your browser – and then try calling one with
fetch()from the console, the way you learned in the last lesson.
“Cannot GET /api/…” means the endpoint doesn’t exist – check for a typo in the address and whether you restarted the server after changing it. “EADDRINUSE” means port 3900 is already in use – you probably have an old server running in another terminal; find it and stop it (Ctrl+C).
Check yourself: Your server runs on port 3900 and responds on several endpoints with your own JSON data. You know the frontend, you’re starting on the backend – all that’s left is connecting them. We’ll do exactly that in the next lesson with a guestbook.
What to take away from this lesson
- A server in Express:
npm init -y,npm install express,node server.js, stop with Ctrl+C, restart after every change. - An endpoint = an address + a response:
app.get("/api/something", (request, response) => response.json(...)). - The frontend (3901) and the backend (3900) are two programs on two ports.
© 2026 Ing. Martin Polak / AlgoRhino · Content usage terms