nodem
A pure JavaScript library for encoding and decoding AX.25 packet radio frames as AFSK audio. Runs in browsers and Node.js with no build step and no dependencies.
AX.25 is the Layer 2 protocol used by amateur radio packet networks including APRS. nodem converts between AX.25 frame objects and Float32Array audio samples, making it straightforward to transmit and receive packet radio signals via a sound card or the Web Audio API.
Live Demo
axchat.kenbarbour.com is a browser-based packet radio chat application built with nodem. It encodes and decodes AX.25 frames in real time directly in the browser using the Web Audio API — no plugins, no install required.
Why nodem?
- Pure JavaScript — no native addons, no compile step, no dependencies
- Works everywhere — Node.js and browsers via the Web Audio API
- Fast — decoding speed comparable to Direwolf, which is written in C
- Accurate — decodes 911 of 1000 packets on TNC Test CD Track 2
- Tested — 100% test coverage
Installation
npm install @kenbarbour/nodem
Usage
import { encoder, decoder } from '@kenbarbour/nodem';
const config = {
sampleRate: 44100, // Hz
baudRate: 1200, // baud
markFreq: 1200, // Hz — binary 1
spaceFreq: 2200, // Hz — binary 0
onPacket: (packet) => console.log(packet),
};
// Encoder: packet object → Float32Array of audio samples
const encode = encoder(config);
const samples = encode({
source: { callsign: 'N0CALL', ssid: 0 },
dest: { callsign: 'APRS', ssid: 0 },
frame: { type: 'U', subtype: 'UI' },
data: 'Hello, World!',
});
// Decoder: stream Float32Array chunks → packets via onPacket callback
const decode = decoder(config);
decode(float32ArrayChunk);
Performance
Benchmarked against the TNC Test CD:
| Track | nodem | Direwolf (C) |
|---|---|---|
| Track 1 | 986 packets | 1005 packets |
| Track 2 | 911 packets | 983 packets |
On the same hardware both run at roughly 85–88× realtime.
License
Found a bug? Report an issue