A desktop application that creates a bridge between serial devices (Arduino, microcontrollers) and web-based creative coding environments like P5.js. Connect multiple devices simultaneously and access their serial data through a simple JavaScript API.
- Features
- Why Serial Bridge?
- Installation
- Quick Start
- API Reference
- Examples
- Configuration
- Troubleshooting
- Contributing
- License
- Support
-
Multiple Arduino Support: Connect and manage multiple Arduino boards simultaneously
-
Real-time Data Streaming: Stream sensor data to your P5.js sketches in real-time
-
Simple API: Clean, beginner-friendly JavaScript client library
-
Cross-Platform: Works on macOS, Windows, and Linux
-
WebSocket Communication: Low-latency bidirectional communication
-
Editable Connection IDs: Customize connection identifiers for better project organization
While the Web Serial API is a great tool, Serial Bridge offers several distinct advantages for creative coding and installation work:
| Feature | Web Serial API | Serial Bridge |
|---|---|---|
| Browser Support | Chrome/Edge only | All Browsers (Chrome, Firefox, Safari) |
| Connection Persistence | Disconnects on page refresh | Stays Connected (Refresh page without losing connection) |
| User Experience | Permission prompt on every visit | Connect Once, use everywhere |
| Multiple Devices | Complex to manage in code | Easy (Manage via UI, access by ID) |
| Security Context | Requires HTTPS | Works on localhost & HTTPS |
Key Advantage: With Serial Bridge, your P5.js sketch doesn't need complex connection logic. You just listen for data. This makes it perfect for:
- Classrooms and workshops (easier for beginners)
- Permanent installations (more robust reconnection)
- Rapid prototyping (refresh your sketch instantly without reconnecting hardware)
Download the latest release for your platform from the Releases page.
Since this app is not signed by Apple, you may see a warning that it "is damaged and can't be opened." To fix this:
- Move the app to your Applications folder.
- Open Terminal and run:
xattr -cr /Applications/Serial\ Bridge.app - You can now open the app normally.
If you are using the .AppImage on Linux (especially Ubuntu 22.04+), you may need to perform a few one-time setup steps.
1. Make Executable
chmod a+x Serial-Bridge-*.AppImage2. Install libfuse2 (Ubuntu 22.04+) AppImages require FUSE to run.
sudo apt install libfuse23. Serial Port Permissions
To access serial ports without sudo, add your user to the dialout group (recommended permanent fix):
sudo usermod -a -G dialout $USERLog out and log back in for this to take effect.
4. Sandbox Issues (Ubuntu 24.04+) If you see a "SUID sandbox helper binary" error, you can either:
- Run with
--no-sandbox:./Serial-Bridge-*.AppImage --no-sandbox - OR enable unprivileged user namespaces (recommended fix):
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
# Clone the repository
git clone https://github.com/IrtizaNasar/SerialBridge.git
cd SerialBridge
# Install dependencies
npm install
# Run in development mode
npm start
# Build for production
npm run build- Launch the Serial Bridge application
- Click "New Connection" to add an Arduino
- Select your Arduino's port from the dropdown
- Click "Connect"
[!TIP] > Identifying Your Board (Windows): On Windows, boards often appear as generic "USB Serial Device". The port list shows the Vendor ID (VID) and Product ID (PID) to help you identify them (e.g.,
2341:0043).
2341is the code for Arduino SA.0043is the code for an Arduino Uno.
Upload this basic sketch to your Arduino:
void setup() {
Serial.begin(9600);
}
void loop() {
int sensorValue = analogRead(A0);
Serial.println(sensorValue);
delay(50);
}[!TIP] > Quick Setup: Use the p5.js Project Generator VS Code extension to instantly generate a P5.js 2.0 project structure.
Include the client library in your HTML:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.min.js"></script>
<script src="http://localhost:3000/socket.io/socket.io.js"></script>
<!-- LOADED FROM THE SERIAL BRIDGEAPP: You do NOT need this file <!-- Serial Bridge Client Library -->
<script src="http://localhost:3000/serial-bridge.js"></script>
<script src="sketch.js"></script>
</head>
<body></body>
</html>Important
The serial-bridge.js script is served dynamically by the Serial Bridge application. You do NOT need to download or copy this file. Just ensure the app is running and the port matches.
Note: The Socket.IO URL should match your bridge server port (default: 3000). The active server URL is displayed in the Serial Bridge application sidebar under "Server URL".
Create your sketch:
let bridge;
let sensorValue = 0;
function setup() {
createCanvas(400, 400);
// Connect to Serial Bridge
bridge = new SerialBridge(); // Auto-detects URL from socket.io script
// OR: bridge = new SerialBridge('http://localhost:3000');
// Listen for data from arduino_1
bridge.onData("arduino_1", (data) => {
sensorValue = parseInt(data);
});
}
function draw() {
background(220);
// Visualize the sensor data
let h = map(sensorValue, 0, 1023, 0, height);
rect(width / 2 - 25, height - h, 50, h);
text(`Value: ${sensorValue}`, 10, 20);
}For most users, you'll only need these methods. The Serial Bridge desktop app handles all connection management through its UI.
Create a new bridge connection:
const bridge = new SerialBridge(serverUrl);
// URL is auto-detected from Socket.IO script tag
// Or specify a custom URL if needed:
const bridge = new SerialBridge("http://localhost:3001");Parameters:
serverUrl(string, optional): Bridge server URL. Auto-detects if not provided.
Receive data from an Arduino connected via the desktop app.
bridge.onData("arduino_1", (data) => {
console.log("Received:", data);
});Parameters:
arduinoId(string): The Arduino connection ID (e.g., 'arduino_1')callback(function): Function called when data is received
Monitor connection status changes.
bridge.onStatus("arduino_1", (status, port) => {
console.log(`Status: ${status}, Port: ${port}`);
});Parameters:
arduinoId(string): The Arduino connection IDcallback(function): Function called when status changes
Send data to a connected Arduino.
await bridge.send("arduino_1", "TOGGLE_LED");Parameters:
arduinoId(string): The Arduino connection IDdata(string): Data to send
Returns: Promise
Listen to all Arduino connections using '*':
bridge.onData("*", (data, id) => {
console.log(`${id} sent: ${data}`);
});
bridge.onStatus("*", (status, port, id) => {
console.log(`${id} is ${status}`);
});Note: The Serial Bridge desktop app must still be running for these methods to work. These methods allow you to manage connections programmatically instead of using the desktop app's UI.
Use these if you want to:
- Build custom web interfaces for connection management
- Create automated systems that connect without user interaction
- Develop custom dashboards or teaching tools
Get list of available serial ports programmatically.
const ports = await bridge.getPorts();
console.log(ports);Returns: Promise
Connect to an Arduino without using the desktop app UI.
await bridge.connectArduino("arduino_1", "/dev/cu.usbmodem14101", 9600);Parameters:
arduinoId(string): The Arduino connection IDportPath(string): Serial port pathbaudRate(number, optional): Baud rate. Default: 9600
Returns: Promise
Disconnect from an Arduino programmatically.
await bridge.disconnectArduino("arduino_1");Parameters:
arduinoId(string): The Arduino connection ID
Returns: Promise
The examples/ directory contains complete working examples:
-
p5js-sketches:
basic-input-p5js: Simple data visualization with a circlebasic-output-p5js: Simple mouseX control of brightnessmulti-input-easy-p5js:Simple data visualization with a circle and squaremulti-input-array-p5js: Visualization of an array of data via primitive shapes.store-input-p5js: Simple data visualization with a circle and saved as a JSON filestore-multi-input-p5js: Visualization of an array of data and stored as a JSON file.bidirectional-interactive-p5js: Simple data visualization with bar chart and line graph
-
arduino-sketches: Example Arduino sketches
basic-send-data.ino: Send analog sensor databasic-recieve.ino: Recieve mouse position data to control analogWrite()send-multi-data.ino: Send two x analog sensor datasend-multi-data-array.ino: Send an array of sensor datainteractive-led.ino: Bidirectional communication with LED control
See examples/README.md for detailed documentation.
SerialBridge/
├── main.js # Electron main process
├── public/ # Bridge application UI
│ ├── index.html
│ ├── styles.css
│ ├── client.js
│ └── arduino-bridge.js # Client library for P5.js
├── examples/ # Example projects
│ ├── basic-p5js/
│ └── arduino-sketches/
└── assets/ # Application icons
The default baud rate is 9600. To use a different rate:
// In your Arduino sketch
Serial.begin(115200);
// When connecting programmatically
await bridge.connectArduino("arduino_1", "/dev/cu.usbmodem14101", 115200);The bridge server runs on port 3000 by default. If port 3000 is already in use, the application will automatically try ports 3001-3004.
The active server URL is always displayed in the application sidebar under "Server URL". Use this URL when including Socket.IO in your P5.js projects.
To change the default starting port, modify serverPort in main.js:
let serverPort = 3000; // Change this to your preferred starting portProblem: Cannot connect to Arduino
- Verify the Arduino is plugged in via USB
- Check that no other application is using the serial port (close Arduino IDE Serial Monitor)
- Try refreshing the port list
- Restart the Serial Bridge application
Problem: Data appears corrupted
- Ensure baud rates match between Arduino and Bridge (default: 9600)
- Use
Serial.println()notSerial.print()in Arduino sketches - Verify data is sent as simple text or numbers
Problem: Bridge connection fails in P5.js
- Verify Serial Bridge application is running
- Check the sidebar in the Bridge app for the server URL (e.g., "http://localhost:3001")
- Update the Socket.IO script URL to match:
<script src="http://localhost:3001/socket.io/socket.io.js"></script> - The
SerialBridge()constructor will auto-detect the URL from the Socket.IO script - Include socket.io client library before arduino-bridge.js
- Check browser console for error messages
Problem: No data received
- Verify Arduino is connected in the Bridge app (green status indicator)
- Check Arduino ID matches (case-sensitive)
- Test with Arduino IDE Serial Monitor first
Contributions are welcome! This project aims to be beginner-friendly and well-documented.
git clone https://github.com/IrtizaNasar/SerialBridge.git
cd SerialBridge
npm install
npm start- Write clear, simple code that beginners can understand
- Add comments explaining non-obvious logic
- Follow existing code formatting
- Test with multiple Arduinos when possible
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
MIT License - see LICENSE file for details
Built with:
- Electron - Desktop application framework
- Express - Web server
- Socket.IO - WebSocket communication
- SerialPort - Serial port access
Designed for use with P5.js - a friendly tool for learning to code and make art.
- Documentation: examples/README.md
- Issues: GitHub Issues
- Discussions: GitHub Discussions




