Run an HTTP server on your Raspberry Pi using Node.js and Express

Learn how to create an Express server that can access your Raspberry Pi from a browser. We'll create a small application that serves up a list of files in the Pi's home directory.

Raspberry PiJavaScript
Node.js logo.
John Persano.
John Persano

Node.js is a trademark of Joyent, Inc. and is used with its permission. We are not endorsed by or affiliated with Joyent.

Raspberry Pi is a trademark of Raspberry Pi Ltd. We are not endorsed by or affiliated with Raspberry Pi Ltd.


If you'd like to get started as soon as possible, follow these steps:

  1. Install Node.js on your Raspberry Pi by running the following commands:
  2. Create and navigate to a project folder it by running the command:
  3. Create a Node.js project and install Express by running the commands:
  4. Copy this Gist into the `express-server` directory.
  5. Start the Express server by running:

I've included more details below if you'd like to learn about Express and step through the code.

Table of contents#

  1. Installing Node.js
  2. Creating an Express server
  3. Stepping Through the Code
  4. Enhancements

Installing Node.js#

I wrote an article titled Install Node.js on your Raspberry Pi that talks about what Node.js is, the details behind the installation procedure, and how to run an example application.

If you're already familiar with Node.js, you can install it on your Raspberry Pi by running the following commands:

Creating an Express server#

Express is a third-party library for Node.js that describes itself as a fast, unopinionated, minimalist web framework for Node.js1. In my opinion, Express makes developing HTTP servers in Node.js more intuitive which is why I chose it for this project.

To get started with Express, we first need to create a new Node.js project. Run the following commands to create a new project called `express-server`:

Next, we'll install the express package with the following command:

With the Express package installed, copy the `main.js` file from this Gist into the `express-server` directory.


You can download the Gist using the following curl command. I strongly encourage you to review the file before running it. Downloading and running files you get from the Internet can be dangerous.

Now that you have the code, run the following command to start the Express server:

Navigating to `localhost:5000/files` in a browser on the Raspberry Pi should now return a JSON list of the files on the system!

TipRun the command ifconfig on the Raspberry Pi to get its IP address. Now use `<ipaddress>:5000/files` to access the endpoint from other devices on your LAN.

Stepping through the code#

In the first few lines of the `main.js` file, we import a few libraries:

The first two libraries, fs and os, come bundled with Node.js itself so there is no need to install them. Express is a third-party library which is why we had to install it using npm.

After importing the libraries, we get a reference to the system's home directory using the os library:

Then, we invoke the function express() which creates the Express server and exposes functions that help us set up endpoints:

Once the Express server is created, we call app.get() which allows us to setup a path and a request handler for that path:

From the code snippet, you can see that the get() function takes two parameters: a path string and a function called a callback. I sometimes refer to the callback function as a request handler.

When performing a GET request to `/files`, Express will invoke the given callback function. The first parameter request will be populated with incoming data such as originating IP address, cookies, and headers. The second parameter response will be populated with methods that allow Express to respond to the request however you'd like.

As an aside, I should mention the naming of get() is no accident. You may add another route to handle POST request types by calling the function You can read more about HTTP methods on

Inside our callback, you'll see a call to fs.readdir() which takes a path parameter and a callback of its own. When fs.readdir() is done reading the file names in the supplied path (or an error occurred), it will invoke the callback with a list of file names. If an error occurred, the error variable will be populated which we handle differently than if the file read was successful. Either way, we use functions provided by response to respond to the request.

After our route is set up, we need to start the Express server:

The function app.listen() takes two parameters, a port number (which I arbitrarily chose to be 5000) and a callback to invoke after the server is started. For the callback, we simply log to console that the server is up so we know that the Express server is ready to respond to requests.

That's all there is to it! To recap, we installed Node.js onto a Raspberry Pi, created a new Node.js, project, installed Express, and started serving up a list of files in the Raspberry Pi home directory.


Want to go further? Here are a few ideas on how to enhance this project:

  1. Create a POST route using that writes files to the system.
  2. Add request logging using the express-winston library.
  3. Add another GET route that returns results from running various vcgencmd commands.

Sign up for blog updates#

Be the first to know about new blog posts from Persanix™ with notifications sent directly to your inbox. No spam, seriously.

By providing your email address you agree that you have read, understood, and agree to the Terms and Conditions and our Privacy Policy.