Minimal ROS bag (v1.2) reader and writer ported from rosbags python implementation.
npm install rosbagsThis directory contains a minimal implementation of a ROS1 (format v2.0)
bag reader and writer in pure JavaScript with zero runtime dependencies.
The only modules it relies on are provided by Node.js itself (fs, path, …), which
means it also works unchanged in the browser after bundling.
The code is a direct, line-for-line port of the
rosbags reference implementation written
in Python. All record layouts, headers and constants are identical, so a bag
produced here can be opened with any existing ROS tooling.
---
``bash`Run the small unit-test suite (writes & reads a few bags)
npm test
`bash`
npm install rosbags
`js
import { Writer, Reader } from 'rosbags';
// Write a bag
const writer = new Writer('example.bag');
writer.open();
const conn = writer.addConnection('/foo', 'std_msgs/msg/Int8');
writer.write(conn, 1n, Buffer.from([0x01]));
writer.close();
// Read a bag
const reader = new Reader('example.bag');
reader.open();
for (const msg of reader.messages()) {
console.log(msg.connection.topic, msg.time, msg.data);
}
reader.close();
`
`js`
const { Writer, Reader } = require('rosbags');
// ...identical to above
Add a single script tag that exposes rosbags globally:
`html`
---
`js
// After installing from npm:
import { Writer } from 'rosbags'; // Node ESM variant
const bag = new Writer('example.bag'); // pass a path ⇒ write to disk
bag.open();
// Register a topic/connection first
const conn = bag.addConnection('/foo', 'std_msgs/msg/Int8');
// Then stream messages (timestamp in nanoseconds)
bag.write(conn, 1n, Buffer.from([0x01]));
bag.write(conn, 2n, Buffer.from([0x02]));
bag.close();
`
`js
import { Writer } from 'rosbags';
const writer = new Writer(); // no path ⇒ keep data in memory
writer.open();
const conn = writer.addConnection('/bar', 'std_msgs/msg/Int8');
writer.write(conn, 42n, new Uint8Array([0xff]));
writer.close();
const raw = writer.getUint8Array(); // Uint8Array containing the .bag file
// …upload, download or feed into a WebWorker here…
`
`js
import { Reader } from 'rosbags';
const reader = new Reader('example.bag');
reader.open();
// Get summary information
for (const conn of reader.connections) {
console.log(topic: ${conn.topic}, type: ${conn.msgtype}, messages: ${conn.msgcount});
}
// Iterate over all messages
for (const msg of reader.messages()) {
console.log(msg.connection.topic, msg.time, msg.data);
}
// Filter by topic
for (const msg of reader.messages({ topics: ['/foo'] })) {
// ...
}
reader.close();
`
`js
import { Reader } from 'rosbags';
// buffer can be an ArrayBuffer or Uint8Array from a file input or fetch`
const reader = new Reader(buffer);
reader.open();
// ... same as reading from disk
---
The tests live in js/tests/:
* test_writer1.js – verifies the writer against a set of hand-rolledtest_writer_rosbag_read.js
assertions (header sizes, chunk flags, …).
– round-trip check that writes with this*rosbag
writer and reads back using the upstream npm dependency.test_reader.js
* - round-trip check that writes with our writer and reads
back with our reader, including complex message types.
Run the suite via:
`bash`
npm test
---
The package.json includes convenience scripts:
* npm run build – Generates self-contained bundles usingdist/rosbags.node.mjs
esbuild:
* (ESM for Node)dist/rosbags.js
* (CommonJS for Node)dist/rosbags.browser.js
* (IIFE for browsers)npm publish
* – Publish the package. A prepublishOnly hook ensures the
bundle is rebuilt and the tests are green before the actual upload.
Everything required at runtime is embedded in the generated bundle, so the
published module stays dependency-free.
---
This JavaScript port is released under the MIT license (see LICENSE`).