AI & Agents

How to Run Node.js on Raspberry Pi for IoT and Agent Projects

The Raspberry Pi 5 scores 764 on Geekbench 6.2 single-core, a 2.4x improvement over Pi 4. That kind of performance makes it a viable host for Node.js servers, JavaScript-based GPIO sensor reads, and always-on agent workloads. The practical setup covers NodeSource installation, Express APIs, real-time dashboards with Socket.io, and keeping everything alive with PM2.

Fast.io Editorial Team 10 min read
Agent workspace connected to edge computing device

Why Node.js Works on Raspberry Pi

The Raspberry Pi 5 scores 764 on Geekbench 6.2 single-core, compared to 340 for the Pi 4. That 2.4x jump comes from the move to quad-core ARM Cortex-A76 processors running at 2.4GHz, along with RAM write speeds that increased from 4,391 MB/s to 29,355 MB/s. These numbers mean the Pi 5 can handle concurrent HTTP requests, process sensor data streams, and run background tasks without choking.

Node.js fits this hardware profile well. Its event-driven, non-blocking I/O model handles multiple simultaneous connections without spawning a thread per request, which matters when you have 4GB or 8GB of RAM instead of 32GB. A Pi running Express can serve API responses to dozens of clients while simultaneously reading temperature sensors, because the event loop keeps everything on a single thread until I/O completes.

JavaScript as a unified language is the other draw. The same developer who builds a React dashboard can write the server that feeds it data and the GPIO code that reads physical sensors. No context-switching between Python for hardware and JavaScript for the web layer. The npm ecosystem provides packages for nearly every peripheral and protocol you would connect to a Pi: I2C, SPI, UART, MQTT, WebSocket, and HTTP.

Self-hosted AI agents add a newer reason to care about Node.js on Raspberry Pi. Projects like OpenClaw, which has accumulated over 160,000 GitHub stars since late 2025, run directly on user hardware rather than in cloud data centers. A Raspberry Pi gives these agents a dedicated, always-on host for under $100 in hardware costs. Node.js handles the HTTP endpoints, WebSocket connections, and file system operations that agent runtimes depend on.

How to Install Node.js on Raspberry Pi

The NodeSource binary distribution is the recommended way to install Node.js on Raspberry Pi. It provides prebuilt ARM binaries that match your Pi's architecture, so you avoid compiling from source.

Start by updating your system packages:

sudo apt update && sudo apt upgrade -y

Install the prerequisites and download the NodeSource GPG key:

sudo apt install -y ca-certificates curl gnupg
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/nodesource.gpg

Add the NodeSource repository. Set NODE_MAJOR to the LTS version you want. Node.js 20 is the current LTS as of mid-2026, and Node.js 22 is available as the active release:

NODE_MAJOR=20
echo "deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list
sudo apt update
sudo apt install -y nodejs

Verify the installation:

node -v
npm -v

You should see version numbers for both Node.js and npm. If you plan to install npm packages that compile native C/C++ addons (like the onoff GPIO library), install the build tools:

sudo apt install -y build-essential

Alternative: NVM for Multiple Versions

If you need to switch between Node.js versions for different projects, Node Version Manager (nvm) gives you that flexibility:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
source ~/.bashrc
nvm install 20
nvm use 20

NVM downloads and compiles from source on ARM, which can take 10 to 20 minutes on a Pi 4. On the Pi 5, compilation finishes faster thanks to the Cortex-A76 cores. The tradeoff is flexibility: nvm lets you run nvm install 22 alongside version 20 and switch between them per terminal session.

Building an Express API Server

A Raspberry Pi running Express becomes a local API endpoint for IoT data collection, home automation controls, or agent communication. Create a project directory and install Express:

mkdir ~/pi-server && cd ~/pi-server
npm init -y
npm install express

Create a basic server in server.js:

const express = require('express');
const os = require('os');
const app = express();

app.use(express.json());

app.get('/status', (req, res) => {
  res.json({
    hostname: os.hostname(),
    uptime: Math.floor(os.uptime()),
    memory: {
      total: Math.floor(os.totalmem() / 1024 / 1024),
      free: Math.floor(os.freemem() / 1024 / 1024)
    },
    cpuTemp: getCpuTemp()
  });
});

function getCpuTemp() {
  try {
    const fs = require('fs');
    const temp = fs.readFileSync(
      '/sys/class/thermal/thermal_zone0/temp', 'utf8'
    );
    return (parseInt(temp) / 1000).toFixed(1) + '°C';
  } catch {
    return 'unavailable';
  }
}

app.listen(3000, '0.0.0.0', () => {
  console.log('Pi server running on port 3000');
});

Binding to 0.0.0.0 instead of localhost makes the server reachable from other devices on your network. Hit http://<your-pi-ip>:3000/status from any browser on the same Wi-Fi to see live CPU temperature and memory stats.

This pattern scales up naturally. Add POST routes for sensor data ingestion, connect to SQLite for local storage, or forward readings to a cloud workspace. For projects where multiple people need access to the data your Pi collects, syncing output files to a shared workspace like Fast.io or an S3 bucket keeps everything accessible without exposing your Pi to the public internet. Fast.io's MCP server also lets AI agents query uploaded sensor logs directly, which is useful if you are building OpenClaw skills or similar agent workflows that need historical data.

Workspace interface showing organized project files
Fastio features

Store your Pi project files in one shared workspace

Shared storage with MCP access. Sync sensor data, agent output, and project files between your Raspberry Pi and the cloud. Starts with a 14-day free trial.

Controlling GPIO Pins with JavaScript

The onoff npm package provides GPIO access through the Linux sysfs interface. It works on all Raspberry Pi models including the Pi 5, though the Pi 5 introduced a new GPIO controller chip (RP1) that changed some internal numbering.

Install onoff:

npm install onoff

Here is a basic example that reads a button on GPIO 17 and toggles an LED on GPIO 27:

const { Gpio } = require('onoff');

const button = new Gpio(17, 'in', 'both');
const led = new Gpio(27, 'out');

button.watch((err, value) => {
  if (err) throw err;
  led.writeSync(value);
});

process.on('SIGINT', () => {
  led.unexport();
  button.unexport();
  process.exit();
});

The 'both' parameter tells onoff to trigger the callback on both rising and falling edges. The SIGINT handler cleans up GPIO exports when you press Ctrl+C, which prevents "resource busy" errors on the next run.

Pi 5 GPIO Changes

The Raspberry Pi 5 uses a different GPIO controller than earlier models. While onoff works on the Pi 5 through the sysfs interface, some developers prefer the newer node-libgpiod package, which uses the modern Linux GPIO character device interface instead of the deprecated sysfs approach:

sudo apt install gpiod libgpiod-dev libnode-dev
npm install node-libgpiod

With node-libgpiod, you reference the GPIO chip directly. On the Pi 5, this is chip 4 rather than chip 0:

const { Chip, Line } = require('node-libgpiod');
const chip = new Chip(4);
const led = new Line(chip, 27);
led.requestOutputMode();
led.setValue(1);

For sensor-heavy projects, the johnny-five framework provides a higher-level API for robotics and IoT. It abstracts away pin numbering and gives you objects like Thermometer, Accelerometer, and Motor instead of raw GPIO reads. The tradeoff is a larger dependency footprint and slightly higher memory usage, which can matter on a Pi Zero or older models with 512MB of RAM.

Streaming Sensor Data with Socket.io

Socket.io adds real-time bidirectional communication between your Pi and any web browser. This is how you build a live dashboard that updates sensor readings without page refreshes.

Install Socket.io alongside Express:

npm install socket.io

Modify your Express server to broadcast sensor data every two seconds:

const express = require('express');
const http = require('http');
const { Server } = require('socket.io');
const fs = require('fs');

const app = express();
const server = http.createServer(app);
const io = new Server(server);

app.use(express.static('public'));

setInterval(() => {
  const temp = fs.readFileSync(
    '/sys/class/thermal/thermal_zone0/temp', 'utf8'
  );
  io.emit('sensor-data', {
    cpuTemp: (parseInt(temp) / 1000).toFixed(1),
    memFree: Math.floor(require('os').freemem() / 1024 / 1024),
    timestamp: Date.now()
  });
}, 2000);

server.listen(3000, '0.0.0.0');

Create a public/index.html file for the browser client:

<div id="temp">Loading...</div>
<script src="/socket.io/socket.io.js"></script>
<script>
  const socket = io();
  socket.on('sensor-data', (data) => {
    document.getElementById('temp').textContent =
      `CPU: ${data.cpuTemp}°C | Free RAM: ${data.memFree}MB`;
  });
</script>

Open http://<pi-ip>:3000 in a browser and you will see live updates every two seconds. Socket.io handles reconnection automatically, so the dashboard recovers if the network drops briefly. You can expand this pattern by adding Chart.js for time-series graphs, storing readings in SQLite for historical queries, or connecting multiple sensor types on different GPIO pins.

For production dashboards that need to persist historical data beyond what fits on an SD card, you can periodically sync sensor logs to cloud storage. Options range from raw S3 uploads to structured platforms. Tools like Fast.io's MCP server let AI agents pull sensor logs from a shared workspace and analyze trends without direct access to your Pi's network, which is useful for remote monitoring setups where the Pi sits behind a firewall.

How to Keep Node.js Running with PM2

A Node.js server that crashes at 3 AM or stops after you close the SSH session is not useful for IoT or agent workloads. PM2 is the standard process manager for keeping Node.js applications alive on Linux, and it works well on Raspberry Pi.

Install PM2 globally:

sudo npm install -g pm2

Start your server with PM2:

pm2 start server.js --name "pi-sensor-api"

PM2 automatically restarts the process if it crashes. To make it survive reboots, run the startup command:

pm2 startup
pm2 save

The startup command generates a systemd service that launches PM2 when the Pi boots. The save command snapshots the current process list so PM2 knows which applications to restart.

Useful PM2 commands for managing your Pi server:

  • pm2 list shows all running processes with CPU and memory usage
  • pm2 logs pi-sensor-api streams the application logs
  • pm2 restart pi-sensor-api restarts the process
  • pm2 monit opens a real-time monitoring dashboard in the terminal

Managing Log Growth

On a Raspberry Pi with limited storage, PM2 logs can grow large over time. This is especially true if you are booting from a 16GB or 32GB SD card. Install the log rotation module to prevent storage exhaustion:

pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 5

This caps each log file at 10MB and keeps the last 5 rotations, which is enough for debugging without filling your SD card.

For projects that generate significant output data, consider offloading files to external storage rather than keeping everything local. You can mount a USB drive for additional capacity, push files to an NFS share on your network, or sync output to a cloud workspace like Fast.io. Keeping your SD card reserved for the operating system and application code extends its lifespan and reduces the risk of corruption from constant writes.

Frequently Asked Questions

Can you run Node.js on Raspberry Pi?

Yes. Node.js runs natively on all Raspberry Pi models with ARM processors. The Pi 5 with its 64-bit Cortex-A76 cores handles Node.js 20 LTS without compatibility issues. Install via NodeSource for prebuilt ARM binaries, or use nvm if you need to switch between versions.

How do I install Node.js on Raspberry Pi?

Update your system with sudo apt update and sudo apt upgrade, download the NodeSource GPG key, add the NodeSource repository for your chosen version (20 for LTS, 22 for the current release), then run sudo apt install nodejs. This installs both Node.js and npm in one step.

Is Node.js good for Raspberry Pi projects?

Node.js is a strong fit for Pi projects that involve network communication, real-time data streaming, or web interfaces. Its event-driven architecture handles concurrent connections efficiently on constrained hardware. Python remains a better choice for pure GPIO scripting or machine learning inference with TensorFlow Lite, so pick based on your project's primary workload.

Can I control GPIO with JavaScript on Raspberry Pi?

Yes. The onoff npm package provides GPIO access on all Pi models including the Pi 5. For the Pi 5 specifically, node-libgpiod uses the newer Linux GPIO character device interface instead of the deprecated sysfs approach. Both packages let you read inputs, write outputs, and respond to hardware interrupts from JavaScript.

How do I keep a Node.js server running on Raspberry Pi after SSH disconnects?

Install PM2 globally with npm install -g pm2, start your app with pm2 start server.js, then run pm2 startup and pm2 save. This creates a systemd service that launches your app automatically when the Pi boots and restarts it if the process crashes.

Which Node.js version should I use on Raspberry Pi?

Node.js 20 LTS is the recommended choice for most projects because it receives security updates and bug fixes through April 2026. Node.js 22 is available as the active release with newer features. Both versions have prebuilt ARM binaries through NodeSource. Avoid odd-numbered releases like 19 or 21, as they do not receive long-term support.

Related Resources

Fastio features

Store your Pi project files in one shared workspace

Shared storage with MCP access. Sync sensor data, agent output, and project files between your Raspberry Pi and the cloud. Starts with a 14-day free trial.