npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

hamlib

v0.6.1

Published

Node.js bindings for Hamlib rig control with official spectrum streaming support

Readme

hamlib

Control amateur radio transceivers from Node.js using the Hamlib library.

Features

  • 300+ Supported Radios - Yaesu, Icom, Kenwood, Elecraft, FlexRadio, and more
  • Full Async/Promise API - Non-blocking operations with async/await support
  • Comprehensive Serial Control - 13 parameters for complete serial port configuration
  • Multiple Connections - Serial ports, network (rigctld), direct control
  • Rotator Bridge - Control antenna rotators through Hamlib's rot_* API with the same Promise-first bridge style
  • Antenna Switching - Rig antenna APIs now use true 1-based antenna numbers and optional antenna option values
  • Official Spectrum Streaming - Wraps Hamlib's official spectrum callback API with Promise helpers and typed events
  • TypeScript Ready - Complete type definitions included
  • Cross-platform - Windows, Linux, macOS

Installation

Option 1: NPM Installation (Recommended)

npm install hamlib

The package will automatically use precompiled binaries if available for your platform, otherwise it will build from source.

Option 2: Manual Prebuilds Installation

For faster installation or offline environments, you can manually install precompiled binaries:

  1. Download Prebuilds: Go to Releases and download hamlib-prebuilds.zip
  2. Extract: Unzip to your project's node_modules/hamlib/prebuilds/ directory
  3. Install: Run npm install hamlib --ignore-scripts

Supported Prebuilt Platforms:

  • ✅ Linux x64
  • ✅ Linux ARM64
  • ✅ macOS ARM64 (Apple Silicon)
  • ✅ Windows x64

Quick Start

const { HamLib, Rotator, PASSBAND } = require('hamlib');

async function main() {
  // Create rig instance (model 1035 = FT-991A)
  const rig = new HamLib(1035, '/dev/ttyUSB0');
  
  await rig.open();
  
  // Basic operations
  await rig.setFrequency(144390000);  // 144.39 MHz
  await rig.setMode('FM', 'nochange');
  
  const freq = await rig.getFrequency();
  const mode = await rig.getMode();
  console.log(`${freq/1000000} MHz ${mode.mode} ${mode.bandwidth}Hz`);
  
  await rig.close();

  // Create rotator instance (model 1 = Dummy rotator)
  const rotator = new Rotator(1);
  await rotator.open();
  await rotator.setPosition(180, 30);
  console.log(await rotator.getPosition());
  await rotator.close();
}

main().catch(console.error);

API Reference

Connection

// Find your radio model
const rigs = HamLib.getSupportedRigs();
const ft991a = rigs.find(r => r.modelName === 'FT-991A');

// Create connection
const rig = new HamLib(1035, '/dev/ttyUSB0');  // Serial
const rig = new HamLib(1035, 'localhost:4532'); // Network (rigctld)

await rig.open();
await rig.close();

Rotator Control

const rotators = Rotator.getSupportedRotators();
const dummy = rotators.find(r => r.modelName === 'Dummy');

const rotator = new Rotator(dummy.rotModel);
await rotator.open();

await rotator.setPosition(135, 20);
const position = await rotator.getPosition();

await rotator.move('RIGHT', 2);
await rotator.stop();

const status = await rotator.getStatus();
const caps = rotator.getRotatorCaps();

await rotator.close();

Basic Control

// Frequency
await rig.setFrequency(14074000);           // 14.074 MHz
const freq = await rig.getFrequency();

// Mode
await rig.setMode('USB');
await rig.setMode('USB', 'nochange');
await rig.setMode('USB', PASSBAND.NOCHANGE);
await rig.setMode('USB', rig.getPassbandNormal('USB'));
const mode = await rig.getMode();
console.log(mode.bandwidth); // Current passband width in Hz

// VFO
await rig.setVfo('VFOA');
const vfo = await rig.getVfo();

// PTT
await rig.setPtt(true);                     // Transmit
const isTransmitting = await rig.getPtt();

// Signal
const strength = await rig.getStrength();

Memory Channels

// Store channel
await rig.setMemoryChannel(1, {
  frequency: 144390000,
  mode: 'FM',
  description: 'Local Repeater'
});

// Recall channel
const channel = await rig.getMemoryChannel(1, true);
await rig.selectMemoryChannel(1);

Advanced Features

// RIT/XIT offsets
await rig.setRit(100);               // +100 Hz RIT
await rig.setXit(-50);               // -50 Hz XIT
await rig.clearRitXit();             // Clear both

// Scanning
await rig.startScan('VFO', 0);       // Start VFO scan
await rig.stopScan();                // Stop scan

// Levels (0.0-1.0)
await rig.setLevel('AF', 0.7);       // Audio 70%
await rig.setLevel('RFPOWER', 0.5);  // TX power 50%
const audioLevel = await rig.getLevel('AF');

// Discrete RF power metadata when Hamlib exposes it
const rfPowerGranularity = rig.getLevelGranularity('RFPOWER');
const rfPowerSteps = rig.getRfPowerStepTable(14074000, 'USB');
console.log(rfPowerGranularity, rfPowerSteps);

// Functions
await rig.setFunction('NB', true);   // Noise blanker on
const voxEnabled = await rig.getFunction('VOX');

// Antenna switching (1-based antenna number)
await rig.setAntenna(2);             // Select antenna 2
await rig.setAntenna(2, 7);          // Select antenna 2 with backend-specific option
const antenna = await rig.getAntenna();
console.log(antenna.currentAntenna, antenna.option);

// Split operation
await rig.setSplit(true);            // Enable split
await rig.setSplitFreq(144340000);   // TX frequency

// VFO operations
await rig.vfoOperation('CPY');       // Copy VFO A to B
await rig.vfoOperation('TOGGLE');    // Toggle VFO A/B

Raw CI-V Request/Reply

const reply = await rig.sendRaw(
  Buffer.from([0xfe, 0xfe, 0xa4, 0xe0, 0x03, 0xfd]),
  64,
  Buffer.from([0xfd])
);

Notes:

  • sendRaw() is request/response oriented.
  • Continuous spectrum streaming now uses Hamlib's official spectrum callback APIs instead of a raw serial byte subscription.
  • The main HamLib class stays a bridge. High-level spectrum helpers live under the hamlib/spectrum subpath.

Official Spectrum Streaming

const { HamLib } = require('hamlib');
const { SpectrumController } = require('hamlib/spectrum');

async function monitorSpectrum() {
  const rig = new HamLib(3085, '/dev/tty.usbmodem11201');
  const spectrum = new SpectrumController(rig);

  await rig.setSerialConfig('rate', '9600');
  await rig.setSerialConfig('data_bits', '8');
  await rig.setSerialConfig('stop_bits', '1');
  await rig.setSerialConfig('serial_parity', 'None');
  await rig.open();

  const support = await spectrum.getSpectrumSupportSummary();
  if (!support.supported) {
    throw new Error('Official Hamlib spectrum streaming is not supported by this rig/backend');
  }

  spectrum.on('spectrumLine', (line) => {
    console.log({
      centerFreq: line.centerFreq,
      spanHz: line.spanHz,
      bins: line.dataLength,
    });
  });

  await spectrum.startManagedSpectrum({
    hold: false,
    spanHz: 10000,
    pumpIntervalMs: 200,
  });

  await new Promise((resolve) => setTimeout(resolve, 15000));

  await spectrum.stopManagedSpectrum();
  await rig.close();
}

Spectrum API summary:

  • HamLib.getSpectrumCapabilities() returns conservative backend metadata exposed by the native addon.
  • HamLib.startSpectrumStream(callback?) registers the official Hamlib spectrum callback only.
  • HamLib.stopSpectrumStream() unregisters the official spectrum callback.
  • SpectrumController.getSpectrumSupportSummary() returns a product-oriented summary of whether official spectrum streaming is usable on the current rig/backend.
  • SpectrumController.configureSpectrum() applies supported SPECTRUM_* levels and optional SPECTRUM_HOLD.
  • SpectrumController.getSpectrumDisplayState() returns a normalized display state with mode/span/fixed edges/edge slot.
  • SpectrumController.configureSpectrumDisplay() applies a normalized display config and reads back the resulting state.
  • SpectrumController.getSpectrumEdgeSlot() / SpectrumController.setSpectrumEdgeSlot() expose backend edge-slot control when available.
  • SpectrumController.getSpectrumFixedEdges() / SpectrumController.setSpectrumFixedEdges() expose direct fixed-range control using SPECTRUM_EDGE_LOW/HIGH.
  • SpectrumController.startManagedSpectrum(config?) runs the validated startup sequence for Icom/Hamlib async spectrum.
    • pumpIntervalMs controls a lightweight helper-side CAT pump. Default 200; set 0 or false to disable.
  • SpectrumController.stopManagedSpectrum() runs the symmetric shutdown sequence and unregisters the callback.

Fixed-range example:

await spectrum.configureSpectrumDisplay({
  mode: 'fixed',
  edgeSlot: 1,
  edgeLowHz: 14074000,
  edgeHighHz: 14077000,
});

const displayState = await spectrum.getSpectrumDisplayState();
console.log(displayState);

Emitted events:

  • HamLib emits spectrumLine when startSpectrumStream() is used without an explicit callback.
  • SpectrumController emits spectrumLine for managed spectrum data.
  • SpectrumController emits spectrumStateChanged when managed spectrum starts or stops.
  • SpectrumController emits spectrumError when managed startup fails asynchronously.

Power and Status

// Power control
await rig.setPowerstat(1);           // Power on (0=off, 1=on, 2=standby)
const powerStatus = await rig.getPowerstat();

// Carrier detection
const carrierDetected = await rig.getDcd();  // Signal present?

// Tuning steps
await rig.setTuningStep(12500);      // 12.5 kHz steps
const step = await rig.getTuningStep();

Repeater Operation

// Set repeater shift
await rig.setRepeaterShift('PLUS');  // '+', '-', or 'NONE'
const shift = await rig.getRepeaterShift();

// Set offset frequency
await rig.setRepeaterOffset(600000); // 600 kHz for 2m
const offset = await rig.getRepeaterOffset();

Serial Configuration

Node-hamlib provides comprehensive serial port configuration with 13 parameters covering all aspects of serial communication from basic data format to advanced timing control and device-specific features.

Important: Serial configuration must be done before calling rig.open().

// Create rig instance
const rig = new HamLib(1035, '/dev/ttyUSB0');

// Configure serial parameters BEFORE opening connection
await rig.setSerialConfig('rate', '115200');           // Baud rate: 150 to 4000000 bps
await rig.setSerialConfig('data_bits', '8');           // Data bits: 5, 6, 7, 8
await rig.setSerialConfig('serial_parity', 'None');    // Parity: None, Even, Odd, Mark, Space
await rig.setSerialConfig('timeout', '1000');          // Timeout in milliseconds
await rig.setSerialConfig('write_delay', '10');        // Inter-byte delay (ms)

// PTT/DCD configuration (also before opening)
await rig.setPttType('DTR');                           // PTT: RIG, DTR, RTS, NONE, etc.
await rig.setDcdType('RIG');                           // DCD: RIG, DSR, CTS, NONE, etc.

// Now open the connection with configured settings
await rig.open();

// Read current settings (can be done anytime)
const rate = await rig.getSerialConfig('rate');
const parity = await rig.getSerialConfig('serial_parity');

Complete Serial Configuration Reference

| Category | Parameter | Description | Supported Values | |----------|-----------|-------------|------------------| | Basic Serial | data_bits | Number of data bits | 5, 6, 7, 8 | | | stop_bits | Number of stop bits | 1, 2 | | | serial_parity | Parity checking | None, Even, Odd, Mark, Space | | | serial_handshake | Flow control | None, Hardware, Software | | Control Signals | rts_state | RTS line state | ON, OFF, UNSET | | | dtr_state | DTR line state | ON, OFF, UNSET | | Communication | rate | Baud rate (bps) | 150 to 4000000 | | | timeout | I/O timeout (ms) | Any non-negative integer | | | retry | Max retry count | Any non-negative integer | | Timing | write_delay | Inter-byte delay (ms) | Any non-negative integer | | | post_write_delay | Inter-command delay (ms) | Any non-negative integer | | Advanced | flushx | MicroHam flush mode | true, false |

Complete Example

const { HamLib } = require('hamlib');

async function repeaterOperation() {
  const rig = new HamLib(1035, '/dev/ttyUSB0');
  
  try {
    await rig.open();
    
    // Set up for 2m repeater
    await rig.setFrequency(145500000);      // 145.500 MHz
    await rig.setMode('FM', 'nochange');
    await rig.setRepeaterShift('MINUS');    // Negative offset
    await rig.setRepeaterOffset(600000);    // 600 kHz offset
    await rig.setTuningStep(12500);         // 12.5 kHz steps
    await rig.setLevel('RFPOWER', 0.5);     // 50% power
    
    // Save to memory
    await rig.setMemoryChannel(1, {
      frequency: 145500000,
      mode: 'FM',
      description: 'W1AW Repeater'
    });
    
    console.log('Setup complete for repeater operation');
    
  } catch (error) {
    console.error('Error:', error.message);
  } finally {
    await rig.close();
  }
}

repeaterOperation();

Supported Radios

Over 300 radio models supported, including:

| Manufacturer | Popular Models | |--------------|----------------| | Yaesu | FT-991A, FT-891, FT-857D, FT-817ND | | Icom | IC-7300, IC-9700, IC-705, IC-7610 | | Kenwood | TS-2000, TS-590SG, TS-890S | | Elecraft | K3, K4, KX3, KX2 | | FlexRadio | 6300, 6400, 6500, 6600, 6700 |

Find your radio model:

const rigs = HamLib.getSupportedRigs();
console.log(rigs.find(r => r.modelName.includes('FT-991')));

Connection Setup

Serial Connection

# Linux/macOS
const rig = new HamLib(1035, '/dev/ttyUSB0');

# Windows
const rig = new HamLib(1035, 'COM3');

Network Connection

# Start rigctld daemon
rigctld -m 1035 -r /dev/ttyUSB0 -t 4532

# Connect from Node.js
const rig = new HamLib(1035, 'localhost:4532');

Troubleshooting

Linux Permissions

sudo usermod -a -G dialout $USER
# Log out and log back in

Find Serial Ports

# Linux
ls /dev/tty*

# macOS  
ls /dev/cu.*

# Test connection
rigctl -m 1035 -r /dev/ttyUSB0 f

License

LGPL - see COPYING file for details.

Links