
Research
/Security News
Coruna Respawned: Compromised art-template npm Package Leads to iOS Browser Exploit Kit
Compromised npm package art-template delivered a Coruna-like iOS Safari exploit framework through a watering-hole attack.
Current version is 2.1.1. More details in CHANGELOG.md.
rpi-io is a lite ESM module for Node.js to control Raspberry Pi GPIO: access (in, out), input event detection and PWM peripheral control.
rpi-io is built on a high performance hybrid architecture based on Node.js + C addon.
rpi-io is designed for recent versions of Raspberry and related OS and middlewares. It has been tested in the following environments:
By default, libgpiod is available with the latest Raspberry Pi OS distributions. If you want to install rpi-io with older - not tested - distributions, be sure it is installed.
sudo apt-get update
sudo apt-get install -y libgpiod-dev gpiod
Then check the installed version
gpioinfo --version
sudo apt-get install -y build-essential python3
Please make sure that you a recent version of Node.js. Recommended tested versions are v23 and further as they support require(esm) by default.
Older versions starting at v20.19 where require(esm) has been backported should work as well, but they haven't been tested extensively.
1. User rights
To run scripts without sudo, add your user to the gpio group.
sudo usermod -a -G gpio $USER
Then log out and log back in.
2. Install the module from your project main directory
cd /your-project
npm install rpi-io
3. Compile C addon from rpi-io directory
cd /your-project/node_modules/rpi-io/
npm install
If you meet errors during this step, stay in the same directory and check your environment.
npm run check
If the error is an alert about high-level vulnerabilities related to the tar module,
npm audit fix --force to install the appropriate version of node-gyp.If you need to recompile the module when errors are fixed, stay in the same directory and the run the following scripts.
npm run clean
npm run install
If you want to use hardware-based PWM peripherals, some configuration is required:
/boot/firmware/config.txt and add the required dtoverlay configuration for PWM as showed in the examples below.sudo nano /boot/firmware/config.txt
# Examples of PWM configuration to add to/boot/firmware/config.txt
# Default one-channel config: GPIO 18 as channel 0
[all]
dtoverlay=pwm
# Default two-channel config: GPIO 18 as channel 0 and GPIO 19 as channel 1
[all]
dtoverlay=pwm-2chan
# Custom two-channel config: GPIO 12 as channel 0 and GPIO 13 as channel 1
[all]
dtoverlay=pwm-2chan,pin=12,func=4,pin2=13,func2=4
# Testing PWM configuration after reboot
pinctrl get 12
# 12: a0 pd | lo // GPIO12 = PWM0_CHAN0
pinctrl get 13
# 13: a0 pd | lo // GPIO13 = PWM0_CHAN1
PLEASE NOTE: In all this document, GPIO line numbers are the BCM ones as defined in https://pinout.xyz/.
GPIO Pin (Output)
│
┌┴┐
│ │ Current-limiting resistor (220Ω or 330Ω)
└┬┘
│
▼ ← LED (anode +)
───
| ← LED (cathode -)
|
───── GND (0V)
─
// Import rpi-io module
import {RIO} from "rpi-io"
// Define instance for OUT operation on some GPIO e.g. 17 with initial value
const led = new RIO(17, "output", {value: 0})
// Turn the led on
led.write(1)
// Turn the led off after 5s and close the instance before leaving
setTimeout(()=>{
led.write(0)
led.close()
}, 5000)
VCC (3.3V)
│
○ ← Switch/Button (open = not pressed)
│
├──────────── GPIO Pin
│
┌┴┐
│ │ Pull-down resistor (10kΩ typical)
└┬┘
│
───── GND (0V)
─
// Import rpi-io module
import {RIO, ctrlC} from "rpi-io"
// Define instance for IN operation on some GPIO e.g. 18
const btn = new RIO(18, "input", {bias: "pull-down"})
// Close instance on script interrupt
ctrlC(() => {
btn.close()
})
// Instant read
console.log("button value:", btn.read())
// Event monitoring for both edges ("rising"/"falling") with rebounce threshold (30)
const callback = edge => {console.log("edge:", edge)}
btn.monitoringStart(callback, "both", 30)
// Stop monitoring after 10s
setTimeout(()=>{
btn.monitoringStop()
}, 10000)
VCC (3.3V)
│
┌┴┐
│ │ Pull-up resistor (10kΩ typical)
└┬┘
│
├──────────── GPIO Pin
│
○ ← Switch/Button (open = not pressed)
│
───── GND (0V)
─
const btn = new RIO(18, "input", {bias: "pull-up"})
REMINDER: PWM peripherals used in hardware mode need some specific [configuration](# Configuration for PWM-based peripherals).
┌─────────────────────┐
│ │
External Power (5V) │ Servo Motor │
│ │ │
│ VCC (red) │ ┌───────────────┐ │
├────────────────────────┤ │ │
│ │ │ Motor │ │
│ GND (brown/black)│ └───────┬───────┘ │
├────────────────────────────────┤ │
│ │ ┌─────┴─────┐ │
│ │ │ Gear │ │
│ │ │ Box │ │
│ │ └─────┬─────┘ │
│ │ ─────┴───── │
│ │ ( Servo Arm ) │
│ Signal (orange) │ │
GPIO Pin ───────────────────────────── │
(PWM) │ │
│ └─────────────────────┘
│
───── Common GND ← Important: Pi GND must connect here
─
import {RIO, sleep, ctrlC, } from "rpi-io"
(async () => {
// Init pwm line (13) and set duty range in µs
const servo = new RIO(13, "pwm", {
period: 20000, // 20,000,000 ns ~ 50 Hz
dutyMin: 500, // 500,000 ns ~ 0.5 ms
dutyMax: 2500 // 2,500,000 ns ~ 2.5 ms
})
ctrlC(() => {
servo.close()
})
await sleep(2000)
servo.pwmDuty(50)
console.log("servo duty = 50%") // ~ 0.5 + (0.5 * (2.5 ms - 0.5 ms)) = 1.5 ms
await sleep(2000)
servo.pwmDuty(100)
console.log("servo duty = 100%") // ~ 0.5 + (1.0 * (2.5 ms - 0.5 ms)) = 2.5 ms
await sleep(2000)
servo.pwmDuty(0)
console.log("servo duty = 0%") // ~ 0.5 + (0.0 * (2.5 ms - 0.5 ms)) = 0.5 ms
await sleep(2000)
servo.close()
console.log("servo closed")
})()
PWM can also be used for progressive LED light with the same electronic circuit as write operations. See example below.
import {RIO, sleep, ctrlC, } from "rpi-io"
(async () => {
// Init pwm line 12 and duty range in µs
const led = new RIO(12, "pwm", {
period: 1000, // 1,000,000 ns ~ 1 KHz
dutyMin: 0,
dutyMax: 1000
})
ctrlC(() => {
led.close()
})
for (let i = 1; i < 101; i++) {
led.pwmDuty(i)
await sleep(30, false)
}
await sleep(2000, false)
led.pwmDuty(0)
led.close()
log("led closed")
})()
MIT
FAQs
Nodejs module to control Raspberry Pi GPIO
The npm package rpi-io receives a total of 86 weekly downloads. As such, rpi-io popularity was classified as not popular.
We found that rpi-io demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
/Security News
Compromised npm package art-template delivered a Coruna-like iOS Safari exploit framework through a watering-hole attack.

Company News
As AI accelerates how code is written and shipped, Socket is scaling to protect the software supply chain from the growing wave of attacks targeting open source dependencies.

Company News
Socket is scaling to defend open source against supply chain attacks as AI accelerates software development.