Skip to main content
Version: 12.x.x

📦 stream

| npm | github |

const { SerialPortStream } = require('@serialport/stream')

This is the Node.js Stream Interface for SerialPort (for more information on Node.js Streams, please see the Stream API docs or one of the numerous independent tutorials). This stream is a Duplex Stream allowing for reading and writing. It has additional methods for managing the SerialPort connection.

You also get the stream interface by requiring the serialport package, which comes with a default set of Bindings and Parsers.

// To get a default set of Bindings and Parsers
const { SerialPort } = require('serialport')


new SerialPortStream(openOptions, [openCallback])

Create a new serial port object. In the case of invalid arguments or invalid options it will throw an error. The port will open automatically by default, which is the equivalent of calling in a process.nextTick. You can disable this by setting the option autoOpen to false in the options.


interface OpenOptions<T extends BindingInterface> extends BindingOpenOptions {
* The hardware access binding. `Bindings` are how Node-Serialport talks to the underlying system. If you're using the `serialport` package, this defaults to `'@serialport/bindings-cpp'` which auto detects Windows (`WindowsBinding`), Linux (`LinuxBinding`) and OS X (`DarwinBinding`) and load the appropriate module for your system.
binding: T

/** Automatically opens the port defaults to true*/
autoOpen?: boolean

* The size of the read and write buffers defaults to 64k
highWaterMark?: number

* Emit 'end' on port close defaults false
endOnClose?: boolean


type openCallback = (Error|null) = {}

Called after a connection is opened. If this is not provided and an error occurs, it will be emitted on the port's error event. The callback will NOT be called if autoOpen is set to false in the openOptions as the open will not be performed.

const serialport = new SerialPort({ path: '/dev/foo-bar', baudRate: 9600, autoOpen: false })


A SerialPort object has several properties.


serialport.baudRate: number

The port's baudRate. Use #update() to change it. Read-only


serialport.port: BindingPort

The BindingPort object backing the stream. Read-only.


serialport.isOpen: Boolean

true if the port is open, false otherwise. Read-only. (since 5.0.0)


serialport.path: string

The path of the serial port. Read-only.


A SerialPort Stream object is a Node.js transform stream and implements the standard data and error events in addition to a few others.


The open event happens when the port is opened and ready for writing. This happens if you have the constructor open immediately (which opens in the next tick) or if you open the port manually with open(). See Usage/Auto Open for more information.


The error provides an error object whenever there is an unhandled error. You can usually handle an error with a callback to the method that produced it. NOTE: If you do not provide a callback, you should have an error handler attached because an unhandled error will cause the process to exit. Please refer to the node documentation for more details.


The close event is emitted when the port is closed. In the case of a disconnect, it will be called with a Disconnect Error object (err.disconnected == true). In the event of an error while closing (unlikely), an error event is triggered.


Listening for the data event puts the port in flowing mode. Data is emitted as soon as it's received. Data is a Buffer object with any amount of data in it. The buffer is only guaranteed to have at least one byte. See the parsers section for more information on how to work with the data, and the Node.js stream documentation for more information on the data event.


The drain event is emitted when it is performant to write again if a write() call has returned false. For more info see the Node.js drain documentation for more info.


open (err: Error | null) => {}): void

Opens the connection of the given serial port. Emits an open event when the port is open, and if provided, calls the callback function after emitting. If the serial port's path does not exist, the callback is invoked with an error message. If no callback handler is provided, the SerialPort object will emit an error event.


serialport.update(options: updateOptions, callback?: err => {}): void

Changes the baud rate for an open port. Throws if you provide a bad argument. Emits an error or calls the callback if the baud rate isn't supported.

updateOptions.baudRate: number The baud rate of the port to be opened. This should match one of the commonly available baud rates, such as 110, 300, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 57600, or 115200. Custom rates are supported best effort per platform. The device connected to the serial port is not guaranteed to support the requested baud rate, even if the port itself supports that baud rate.

callback: error => {}: void Called once the port's baud rate changes. If .update is called without a callback, and there is an error, an error event is emitted.


serialport.write(data: string|Buffer|Array<number>, encoding?: string, callback?: error => {}): boolean

Writes data to the given serial port. Buffers written data if the port is not open and writes it after the port opens. The write operation is non-blocking. When it returns, data might still not have been written to the serial port. See drain().

Some devices, like the Arduino, reset when you open a connection to them. In such cases, immediately writing to the device will cause transmitted data to be lost as the devices won't be ready to receive the data. This is often worked around by having the Arduino send a "ready" byte that your Node program awaits before writing. You can also often get away with waiting a set amount, around 400ms. See the ReadyParser for a solution to this.

If a port is disconnected during a write, the write will produce an error in addition to the close event.

According to the stream docs, write errors don't always provide the error in the callback; sometimes they use the error event.

If an error occurs, the callback may or may not be called with the error as its first argument. To reliably detect write errors, add a listener for the 'error' event.

While this is in the stream docs, it hasn't been observed.

In addition to the usual stream.write arguments (String and Buffer), write() can accept an array of bytes (positive numbers under 256) which is passed to Buffer.from([]) for conversion.


  • data: string|Buffer|Array<number>
  • encoding?: string The encoding, if chunk is a string. Defaults to 'utf8'. Also accepts 'ascii', 'base64', 'binary', and 'hex' See Buffers and Character Encodings for all available options.
  • callback?: error => {} Called once the write operation finishes. Data may not yet be drained to the underlying port.

Returns false if the stream wishes for the calling code to wait for the drain event to be emitted before continuing to write additional data; otherwise true.

read number): string|Buffer|null

Request a number of bytes from the SerialPort. The read() method pulls some data out of the internal buffer and returns it. If no data is available to be read, null is returned. By default, the data is returned as a Buffer object unless an encoding has been specified using the .setEncoding() method.


  • size?: number Specify how many bytes of data to return, if available


serialport.close(callback?: error => {}): void

Closes an open connection. If there are in-progress writes when the port is closed the writes will error.


  • `callback?: (error => {}: void) Called once a connection is closed.


serialport.set(options: setOptions, callback?: error => {}): void

Set control flags on an open port. Uses SetCommMask for Windows and ioctl for OS X and Linux.


  • options: setOptions All options default to the operating system defaults when the port is opened. Every flag is set on each call to the provided or default values.
  • callback: error => {} Called once the port's flags have been set.


* {Boolean} [setOptions.brk=false] sets the brk flag
* {Boolean} [setOptions.cts=false] sets the cts flag
* {Boolean} [setOptions.dsr=false] sets the dsr flag
* {Boolean} [setOptions.dtr=true] sets the dtr flag
* {Boolean} [setOptions.rts=true] sets the rts flag
* {Boolean} [setOptions.lowLatency=true] enables low latency mode (linux specific - admin rights may be required)


serialport.get(callback: (error, data: ModemStatus) => {}): void

Returns the control flags (CTS, DSR, DCD) on the open port. Uses GetCommModemStatus for Windows and ioctl for mac and linux.

* {boolean} [ModemStatus.cts=false]
* {boolean} [ModemStatus.dsr=false]
* {boolean} [ModemStatus.dcd=false]
* {boolean} [ModemStatus.lowLatency=false] (Linux Specific)


serialport.flush(callback? error => {}):void

Flush discards data that has been received but not read, or written but not transmitted by the operating system. For more technical details, see tcflush(fd, TCIOFLUSH) for Mac/Linux and PurgeComm for Windows.

  • callback? error => {} Called once the flush operation finishes.


serialport.drain(callback? error => {}):void

Waits until all output data is transmitted to the serial port. After any pending write has completed, it calls tcdrain() or FlushFileBuffers() to ensure it has been written to the device.

  • callback? error => {} Called once the drain operation returns.

Drain Example

A function to write data and wait until it has finished transmitting to the target serial port before calling the callback. This will wait until the port is open and writes are finished as determined by the operating system.

function writeAndDrain (data, callback) {


serialport.pause(): this

The pause() method causes a stream in flowing mode to stop emitting 'data' events, switching out of flowing mode. Any data that becomes available remains in the internal buffer.


serialport.resume(): this

The resume() method causes an explicitly paused, Readable stream to resume emitting 'data' events, switching the stream into flowing mode.