Hi all,
rclnodejs 2.1.0 is out — and it’s a step toward making rclnodejs a web-native SDK for ROS 2: a platform for bringing ROS 2 to the browser and the modern JavaScript ecosystem. With 2.1.0, the whole package is now native ESM, so building web dashboards, teleop UIs, and browser bridges on ROS 2 feels native to today’s web tooling — with the full ROS 2 runtime still underneath whenever you need real nodes.
TL;DR — 2.1.0 makes rclnodejs native ESM end-to-end. import rclnodejs from 'rclnodejs' just works, the browser SDK (rclnodejs/web) brings ROS 2 to the web, and existing require() nodes keep running untouched — the full ROS 2 runtime is still underneath.
A web-native SDK for ROS 2
- ROS 2 on the web — reach ROS 2 from a web page with
rclnodejs/web: typed APIs over WebSocket, no proxy, no codegen.
- Native ESM — first-class
import and top-level await, ready for Vite/esbuild and the modern web toolchain.
- Full ROS 2 runtime underneath — real nodes, pub/sub, services, actions, parameters, lifecycle, whenever you need them.
- Backward compatible — every existing CommonJS (
require) project upgrades with zero code changes.
One package, both module systems
// Modern Node / browser — ESM
import rclnodejs from 'rclnodejs'; // full ROS 2 node API
import { connect } from 'rclnodejs/web'; // typed browser SDK
// Existing CommonJS nodes — unchanged
const rclnodejs = require('rclnodejs');
Where this is heading
Each release moves rclnodejs one step closer to a typed, web-native way into ROS 2:
- 2.0.0
— a typed browser SDK (rclnodejs/web) backed by a capability runtime that exposes only what web.json declares, with HTTP call / publish for non-JS clients.
- 2.1.0
— native ESM across the whole package, so rclnodejs sits naturally alongside the rest of your web stack.
The arc: from “a Node.js client that happens to run in browsers” → “a typed, allow-listed Web SDK for ROS 2”
Try it
npm i rclnodejs
Feedback welcome — especially from anyone wiring ROS 2 into web frontends. 
Cheers,
Minggang
1 Like
rclnodejs 2.1.1: SSE Support for Streaming Robot Data to the Web
rclnodejs 2.1.1 is out, adding Server-Sent Events (SSE) subscribe support to the web-native HTTP transport described above. Browsers can now stream live ROS 2 topic data with just the built-in EventSource API — no WebSocket, no SDK, no codegen.
Builds on 2.1.0’s native ESM and the rclnodejs/web HTTP transport from 2.0.0: same capability runtime, now with a subscribe path over SSE alongside the existing call/publish.
Streaming topics into the browser
# Terminal 1
# source /opt/ros/<distro>/setup.bash
ros2 run demo_nodes_cpp talker # publishes /chatter
# Terminal 2
# source /opt/ros/<distro>/setup.bash
npx -p rclnodejs rclnodejs-web --port 9000 --http-port 9001 \
--http-sse --http-cors '*' --subscribe /chatter=std_msgs/msg/String
// Browser — no SDK needed
const source = new EventSource(
'http://localhost:9001/capability/subscribe/chatter'
);
source.addEventListener('message', (e) => console.log(JSON.parse(e.data)));
GET /capability/subscribe/<name> streams as text/event-stream; --http-cors lets cross-origin pages connect too, and --http-sse-keep-alive <ms> controls the heartbeat interval. Full walkthrough: demo/web/javascript/.
Useful anywhere you want live robot data outside a ROS-aware process — a browser dashboard showing topic data in real time, or an agent/LLM tool that subscribes to a topic over plain HTTP instead of speaking ROS 2 natively.
Feedback welcome.
Cheers,
Minggang
2 Likes
rclnodejs 2.2.0-beta.0: ROS 2 Capabilities as Discoverable, Agent-Ready OpenAPI 3.1 APIs
Your web.json allow-list can now describe itself: rclnodejs 2.2.0-beta.0 — the first preview of the 2.2 line — adds an openapi subcommand that emits a standard OpenAPI 3.1 document, so API explorers, codegen, and AI-agent tool-use all get a machine-readable description of your ROS 2 graph for free, no hand-written shim required.
Builds on the rclnodejs/web capability runtime from 2.0.0/2.1.1: the same call/publish/subscribe capabilities you already expose over WebSocket and HTTP, now also describable as one static JSON document.
Generating a document
source /opt/ros/<distro>/setup.bash
npx -p rclnodejs@2.2.0-beta.0 rclnodejs-web openapi web.json > openapi.json
Viewing the document in Swagger UI
The document is plain static JSON, so any OpenAPI viewer works — point Swagger UI at it (no server-side integration needed, just load openapi.json from a CDN build) to get a browsable, “try it out” API reference for your ROS 2 graph:
Full walkthrough: demo/web/javascript/.
Cheers,
Minggang
rclnodejs 2.2.0: Automatic Reconnection for the Web SDK
rclnodejs 2.2.0 is out. RosClient’s reconnect option is now implemented
import { connect } from 'rclnodejs/web';
const ros = await connect('ws://localhost:9000', { reconnect: true });
ros.on('disconnected', () => console.log('connection lost'));
ros.on('reconnecting', ({ attempt, delay }) => console.log(`retry ${attempt} in ${delay}ms`));
ros.on('reconnected', () => console.log('back online'));
Also new: OpenAPI 3.1 export + Swagger UI for the HTTP transport (previewed in 2.2.0-beta.0), and ROS 2 action-graph query APIs (countActionClients/countActionServers, ActionEndpointInfo).
Cheers,
Minggang
1 Like