0% completed
Setting Up a Basic Express Server
On This Page
Create the Project
Write the Server
Run It and Send a Request
Restart Automatically When a File Changes
When the Port Is Already in Use
A working Express server needs one npm package and about a dozen lines of code. The steps below create a project folder for the task API that the following lessons build. They install Express into it and start a server that answers its first request.
Create the Project
Open a terminal, create a folder for the project, and move into it. Then create a package.json file and install Express:
mkdir task-api cd task-api npm init -y npm install express
The command npm init -y writes a package.json file with default values, and npm install express downloads Express into a node_modules folder and records it as a dependency. You can confirm which version was installed:
npm ls express
task-api@1.0.0 /home/you/task-api `-- express@5.3.0
The dependency now appears in package.json as "express": "^5.3.0". The caret means that a later npm install may pick a newer 5.x release, but never version 6. Your version number may be higher than 5.3.0, and that is fine for this course.
Recent versions of npm also write "type": "commonjs" into package.json. That setting tells Node.js to treat .js files as CommonJS modules, which load other modules with require(). The course uses require() throughout.
Write the Server
Create a file named server.js in the project folder with this content:
const express = require('express'); const app = express(); const PORT = process.env.PORT || 3000; app.get('/', (req, res) => { res.send('Task API is running'); }); app.listen(PORT, (error) => { if (error) { throw error; } console.log(`Server is running on port ${PORT}`); });
The file does four things in order. It loads Express, and it calls express() to create the application object, named app by convention. It then registers a route: when a GET request arrives for the path /, Express calls the handler, and the handler sends a short text response with res.send().
Finally, app.listen() starts an HTTP server on the port. The port comes from the environment variable PORT when one is set, and it is 3000 otherwise. Hosting platforms usually tell an app which port to use through PORT, so reading it now avoids a change later.
The callback of app.listen() runs once, when the server either starts or fails to start. In Express 5, the callback receives an error argument when the server cannot start, and the code above rethrows that error so that the failure is visible. Express 4 never passed an error to this callback, so older examples usually take no parameter.
Run It and Send a Request
Start the server from the project folder:
node server.js
Server is running on port 3000
The process keeps running, because the server is now waiting for connections. Open http://localhost:3000/ in a browser, and the page shows the text Task API is running. To see the whole response, including its headers, send the request from a second terminal with curl -i:
curl -i http://localhost:3000/
HTTP/1.1 200 OK X-Powered-By: Express Content-Type: text/html; charset=utf-8 Content-Length: 19 ETag: W/"13-B3NnK2iCKqXh1+X+ElqeomzgAMQ" Connection: keep-alive Keep-Alive: timeout=5 Task API is running
The handler wrote only the body, and Express added the rest. Because res.send() received a string, Express set Content-Type to HTML. It counted the 19 bytes of the body for Content-Length. It also computed an ETag, which is a short fingerprint of the body that a browser can use to ask whether the content has changed since its last visit. The X-Powered-By: Express header tells every client which framework runs the server, and chapter 6 shows how to remove it.
Stop the server with Ctrl+C in the terminal where it runs.
Restart Automatically When a File Changes
A running Node.js process does not reload server.js when you edit it, so after every change you would have to stop and start the server again. Node.js can do that for you with the --watch flag:
node --watch server.js
When you save a change to server.js, or to any file that it loads, Node.js stops the server, clears the terminal, prints a notice, and starts the server again. After a save, the terminal shows:
Restarting 'server.js' Server is running on port 3000
To keep the earlier output on the screen instead, add the flag --watch-preserve-output.
Before Node.js had this flag, developers installed the nodemon package for the same purpose, and many projects still use it. It works, but for this course the built-in flag is enough and needs no extra package.
To avoid typing the commands each time, add two scripts to the scripts section of package.json:
"scripts": { "start": "node server.js", "dev": "node --watch server.js" }
Now npm run dev starts the server in watch mode while you work, and npm start starts it the normal way.
When the Port Is Already in Use
Only one process can listen on a port at a time. If you start a second copy of the server while the first one still runs, the second one cannot start, and the error reaches the callback of app.listen(). Because the callback rethrows it, Node.js prints the error and the process exits:
Error: listen EADDRINUSE: address already in use :::3000 at Server.setupListenHandle [as _listen2] (node:net:2008:16) ... code: 'EADDRINUSE', syscall: 'listen', port: 3000
The code EADDRINUSE means that the address is in use. Stop the other process, or start this one on another port. In a macOS or Linux shell, the command is PORT=3001 node server.js, and in Windows PowerShell it is $env:PORT=3001; node server.js.
Reading Progress
0%
On This Page
Create the Project
Write the Server
Run It and Send a Request
Restart Automatically When a File Changes
When the Port Is Already in Use