New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

webserial-core

Package Overview
Dependencies
Maintainers
1
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

webserial-core

A strongly-typed, event-driven, abstract TypeScript library for the Web Serial API with custom parsers, command queue, handshake validation, and auto-reconnect.

latest
Source
npmnpm
Version
2.0.1
Version published
Maintainers
1
Created
Source

webserial-core

npm version npm downloads License: MIT TypeScript bundle size GitHub release Ask DeepWiki

A strongly-typed, event-driven, abstract TypeScript library for serial communication on the web. Supports Web Serial, WebUSB, Web Bluetooth, and WebSocket transports through a unified API.

⚠️ Breaking Changes — v2

Version 2 is a complete rewrite. Tthe public API is completally changed, please if you has an implementation of this library is better read docs as like a new integration See the Migration Guide before upgrading.

Features

  • Provider-agnostic — swap between Web Serial, WebUSB, Web Bluetooth, or WebSocket transport by injecting a single provider.
  • Strictly typed — full TypeScript generics, no implicit any, compatible with strict: true.
  • Typed eventsconnecting, connected, disconnected, data, sent, error, timeout, reconnecting, and more — all fully typed.
  • Built-in parsersdelimiter, fixedLength, raw. Implement SerialParser<T> for any custom binary or text protocol.
  • Command queue — FIFO write queue with optional per-command timeouts.
  • Auto-reconnect — configurable reconnect loop with back-off.
  • WebUSB polyfill — full WebUSB serial polyfill (CDC ACM, CP210x, CH340).
  • BLE NUS adapter — Nordic UART Service over Web Bluetooth GATT.
  • WebSocket bridge — relay serial I/O through a Node.js bridge server.

Installation

npm install webserial-core

Quick start

import { AbstractSerialDevice, delimiter } from "webserial-core";

class MyDevice extends AbstractSerialDevice<string> {
  constructor() {
    super({
      baudRate: 9600,
      parser: delimiter("\n"),
      autoReconnect: true,
    });
  }

  protected async handshake(): Promise<boolean> {
    return true; // return false to reject the port
  }
}

const device = new MyDevice();

device.on("serial:connected", () => console.log("Connected!"));
device.on("serial:data", (line) => console.log("←", line));
device.on("serial:disconnected", () => console.log("Disconnected."));
device.on("serial:error", (err) => console.error(err.message));

await device.connect(); // opens the browser port picker
await device.send("PING\n"); // enqueues a write
await device.disconnect();

Transport adapters

All four adapters expose the same SerialProvider interface. Inject your chosen adapter once before constructing any device:

import { AbstractSerialDevice, WebUsbProvider } from "webserial-core";
import { createBluetoothProvider } from "webserial-core";
import { createWebSocketProvider } from "webserial-core";

// WebUSB polyfill (Android Chrome, or desktop for testing)
AbstractSerialDevice.setProvider(new WebUsbProvider());

// Web Bluetooth (Nordic UART Service over BLE GATT)
AbstractSerialDevice.setProvider(createBluetoothProvider());

// WebSocket bridge (requires Node.js server — see demos/websocket/)
AbstractSerialDevice.setProvider(
  createWebSocketProvider("ws://localhost:8080"),
);

Parsers

import { delimiter, fixedLength, raw } from "webserial-core";

// Newline-delimited strings (Arduino Serial.println)
parser: delimiter("\n");

// 16-byte binary packets
parser: fixedLength(16);

// Raw Uint8Array chunks
parser: raw();

Events

EventPayloadDescription
serial:connectingconnect() called, port picker about to open
serial:connectedPort open, handshake passed
serial:disconnectedPort closed
serial:dataTParser emitted a complete message
serial:sentUint8ArrayBytes written to the port
serial:errorErrorUnrecoverable error
serial:need-permissionUser denied access
serial:timeoutUint8ArrayCommand timed out
serial:queue-emptyWrite queue is now idle
serial:reconnectingAuto-reconnect attempt starting

Project structure

src/
  core/           AbstractSerialDevice, SerialEventEmitter, SerialRegistry
  adapters/
    web-usb/      WebUsbProvider (WebUSB polyfill)
    web-bluetooth/ createBluetoothProvider (BLE NUS)
    websocket/    createWebSocketProvider (Node.js bridge)
  parsers/        delimiter, fixedLength, raw
  queue/          CommandQueue
  errors/         SerialPortConflictError, SerialPermissionError, …
  types/          SerialDeviceOptions, SerialProvider, SerialParser, …
demos/
  web-serial/     Native Web Serial demo
  web-usb/        WebUSB polyfill demo
  web-bluetooth/  Web Bluetooth BLE demo
  websocket/      WebSocket bridge demo + Node.js server
docs/             VitePress documentation site

Building

npm run build

Output in dist/:

FileFormatUse case
webserial-core.mjsESMBundlers, modern browsers
webserial-core.cjsCJSNode.js, legacy bundlers
webserial-core.umd.cjsUMD<script> tag, CDN
index.d.tsTypeScriptType declarations

Documentation

npm run docs:dev   # live VitePress server
npm run docs:build # static build → docs/.vitepress/dist

Browser compatibility

FeatureBrowser requirement
Web SerialChrome 89+, Edge 89+
WebUSBChrome 61+, Edge 79+
Web BluetoothChrome 56+, Edge 79+
WebSocketAll modern browsers

All browser APIs require a secure context (HTTPS or localhost).

License

MIT © danidoble

Keywords

webserial

FAQs

Package last updated on 22 Mar 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts