SerialPilot

/02 — Reference

Core API

The SerialPilot class is a Node.js Duplex stream — read it, write to it, pipe it. Everything below is exposed from the top-level serialpilot package; subpackages mirror the same names if you prefer to install à la carte.

Import

// CommonJS
const { SerialPilot, ReadlineParser } = require('serialpilot')

// ESM / TypeScript import { SerialPilot, ReadlineParser } from ‘serialpilot’

new SerialPilot(options, callback?)

Open a port. Returns a Duplex stream that emits open when the underlying device is ready.

const port = new SerialPilot({
path: '/dev/ttyUSB0',
baudRate: 115200,
dataBits: 8,
parity: 'none',
stopBits: 1,
})

Constructor options

OptionTypeDefaultNotes
pathstringRequired. Device path (e.g. /dev/ttyUSB0, COM3).
baudRatenumberRequired. 9600, 115200, etc.
dataBits5 | 6 | 7 | 88
parity'none' | 'even' | 'odd' | 'mark' | 'space''none'Modbus RTU usually wants 'even'.
stopBits1 | 1.5 | 21
autoOpenbooleantrueIf false, call port.open() manually.
highWaterMarknumber65536Stream buffer size in bytes.
endOnClosebooleanfalseEnd the stream when the port closes.
rtscts / xon / xoff / xanybooleanfalseHardware / software flow control.
hupclbooleantrueHang up on close (Unix).
bindingBindingInterfaceauto-detectOverride for tests; see Mocking.

The optional second argument is a callback fired after the port opens (or fails to). If you prefer promises, listen for the open event instead.

Static methods

SerialPilot.list()

Resolves to an array of every serial port the OS knows about. Each entry has path, manufacturer, serialNumber, vendorId, productId, pnpId, and locationId (any of which may be undefined).

const ports = await SerialPilot.list()

SerialPilot.findPorts(filter)

Like list() but filters the result. The filter accepts strings (case-insensitive equality) or regular expressions:

const arduinos = await SerialPilot.findPorts({
manufacturer: /arduino/i,
})

const byVid = await SerialPilot.findPorts({ vendorId: ‘2341’, productId: ‘0043’, })

Filter keys: vendorId, productId, serialNumber, manufacturer, path.

SerialPilot.openByDevice(options)

Discovery and open in a single call. Useful when the path may shift (different USB host, different OS) but the device fingerprint stays put.

const port = await SerialPilot.openByDevice({
vendorId: '2341',
baudRate: 115200,
required: true, // throws PortNotFoundError if no match (default)
})

Pass required: false to receive undefined instead of throwing when no port matches.

SerialPilot.parsers

A static record of every parser, in case you'd rather not import them by name:

SerialPilot.parsers.Readline
SerialPilot.parsers.Delimiter
SerialPilot.parsers.ByteLength
SerialPilot.parsers.Regex
SerialPilot.parsers.PacketLength
SerialPilot.parsers.InterByteTimeout
SerialPilot.parsers.Ready
SerialPilot.parsers.SlipEncoder
SerialPilot.parsers.SlipDecoder
SerialPilot.parsers.CCTalk
SerialPilot.parsers.SpacePacket
SerialPilot.parsers.StartEnd

Instance methods

MethodReturnsNotes
port.write(data, encoding?, cb?)booleanStandard Writable. Returns false when the buffer is full — wait for drain.
port.read(size?)Buffer | nullStandard Readable.
port.pipe(stream)destinationPipe into a parser or any Writable.
port.open(cb?)voidOnly needed when constructed with autoOpen: false.
port.close(cb?)voidCloses and emits close.
port.update(options, cb?)voidChange baud rate without closing.
port.set(options, cb?)voidToggle DTR / RTS / BRK / DSR / CTS lines.
port.get(cb)voidRead CTS / DSR / DCD line state.
port.flush(cb?)voidDiscard buffered data on both directions.
port.drain(cb?)voidWait for the OS write buffer to empty.
port.isOpenbooleanProperty, not a method.

Events

EventPayloadWhen
openFired once, when the port is ready for I/O.
dataBufferBytes from the device. Inherited from Readable.
drainThe internal write buffer has emptied.
closeerr?Port has closed; an Error indicates a disconnect.
errorErrorAnything went wrong. See Errors.
endThe stream's read side ended.

Common patterns

Open as a promise

function openPort(opts) {
return new Promise((resolve, reject) => {
const port = new SerialPilot(opts)
port.once('open', () => resolve(port))
port.once('error', reject)
})
}

Close as a promise

await new Promise((res, rej) =>
port.close(err => err ? rej(err) : res())
)

Honour backpressure

if (!port.write(buf)) {
await new Promise(res => port.once('drain', res))
}
Heads up SerialPilot extends Node's Duplex, so anything that works on a stream — async iteration, pipeline, finished — works here too.

Edit this page on GitHub