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

@sourceregistry/node-ovsdb

v1.0.4

Published

TypeScript OVSDB client for Node.js

Downloads

30

Readme

@sourceregistry/node-ovsdb

License npm version codecov Release to NPM

Low-level OVSDB client for Node.js with:

  • Unix socket, TCP, and TLS transports
  • RFC 7047 core RPC support
  • Open vSwitch monitor extensions
  • typed transaction and monitor payloads
  • event-driven notifications
  • schema-to-TypeScript generation CLI
  • TSDoc-ready public API for Typedoc

Installation

npm install @sourceregistry/node-ovsdb

Generate types from a schema with:

npx ovsdb-generate --help

What It Supports

The client is intentionally low-level and maps closely to the wire protocol.

  • list_dbs
  • get_schema
  • transact
  • cancel
  • monitor
  • monitor_cond
  • monitor_cond_since
  • monitor_cancel
  • lock
  • steal
  • unlock
  • echo
  • set_db_change_aware
  • notifications: update, update2, update3, locked, stolen

Quick Start

Unix socket:

import {OVSDBClient} from "@sourceregistry/node-ovsdb";

const client = new OVSDBClient({
  socketPath: "/var/run/openvswitch/db.sock",
  timeout: 5000
});

try {
  await client.connect();

  const databases = await client.listDbs();
  const schema = await client.getSchema("Open_vSwitch");

  console.log(databases, schema.version);
} finally {
  await client.close();
}

Plain TCP:

import {OVSDBClient} from "@sourceregistry/node-ovsdb";

const client = new OVSDBClient({
  host: "127.0.0.1",
  port: 6640
});

TLS:

import {OVSDBClient} from "@sourceregistry/node-ovsdb";

const client = new OVSDBClient({
  host: "ovsdb.example.internal",
  port: 6640,
  tls: true,
  tlsOptions: {
    servername: "ovsdb.example.internal",
    rejectUnauthorized: true
  }
});

Schema Generation

The package includes an ovsdb-generate CLI that emits TypeScript row and database model types you can use with OVSDBClient<...>.

Generate from a checked-in schema file:

npx ovsdb-generate --schema ./Open_vSwitch.schema.json --out ./src/generated/ovsdb.ts

Generate directly from a live OVSDB server:

npx ovsdb-generate --socket /var/run/openvswitch/db.sock --db Open_vSwitch --out ./src/generated/ovsdb.ts

Generate from a live TCP endpoint:

npx ovsdb-generate --host 127.0.0.1 --port 6640 --db Open_vSwitch --out ./src/generated/ovsdb.ts

Generate from a live TLS endpoint:

npx ovsdb-generate \
  --host ovsdb.example.internal \
  --port 6640 \
  --tls \
  --tls-ca-file ./pki/ca.pem \
  --tls-cert-file ./pki/client.pem \
  --tls-key-file ./pki/client.key \
  --db Open_vSwitch \
  --out ./src/generated/ovsdb.ts

You can override the generated top-level type name with --name OpenVSwitchDb.

Typed Transactions

You can provide your own table model to get typed table names, rows, selected columns, conditions, mutations, and tuple-shaped transaction results.

import {OVSDBClient, type DatabaseOperation, type OvsSet} from "@sourceregistry/node-ovsdb";

type OpenVSwitchDb = {
  Bridge: {
    name: string;
    ports: OvsSet<string>;
  };
  Port: {
    name: string;
    interfaces: OvsSet<string>;
  };
};

const client = new OVSDBClient<OpenVSwitchDb>();
await client.connect();

const operations = [
  {
    op: "select",
    table: "Bridge",
    where: [["name", "==", "br-int"]],
    columns: ["name", "ports"]
  },
  {
    op: "insert",
    table: "Port",
    row: {
      name: "uplink0",
      interfaces: ["set", []]
    }
  }
] satisfies [DatabaseOperation<OpenVSwitchDb>, DatabaseOperation<OpenVSwitchDb>];

const [bridges, insertedPort] = await client.transact("Open_vSwitch", operations);

For a higher-level staged flow, use client.transaction(...). The callback can build operations against a transaction-scoped helper, and the library will send one transact request only if the callback completes successfully. By default it appends a trailing commit operation automatically.

const outcome = await client.transaction("Open_vSwitch", (tx) => {
  tx.comment("prepare bridge lookup");
  tx.select({
    op: "select",
    table: "Bridge",
    where: [["name", "==", "br-int"]],
    columns: ["name"]
  });

  return "ok";
});

Monitoring

import {OVSDBClient} from "@sourceregistry/node-ovsdb";

const client = new OVSDBClient();
await client.connect();

client.on("update", (notification) => {
  const [monitorId, updates] = notification.params;
  console.log("monitor", monitorId, updates);
});

await client.monitor("Open_vSwitch", "bridges", {
  Bridge: {
    columns: ["name"],
    select: {
      initial: true,
      insert: true,
      modify: true,
      delete: true
    }
  }
});

For conditional monitoring, use monitorCond() or monitorCondSince().

Detect When an Interface Is Attached to a Bridge

OVSDB does not usually emit a single semantic event like "interface attached to bridge". Instead, you observe the row changes that together mean an attachment happened:

  • a new Interface row may appear
  • a new Port row may appear
  • an existing Bridge row may be modified so its ports set now includes that port

In practice, the bridge update is usually the strongest signal that something was attached to the virtual switch.

Why this works:

  • the Bridge.ports column is the relationship that tells you which ports are attached to the bridge
  • when that set grows, something new was connected to the bridge
  • you can then inspect Port and Interface tables to resolve names or metadata for the newly attached objects

If you want richer correlation, monitor Bridge, Port, and Interface together and keep a small in-memory cache keyed by UUID so you can map a changed bridge port set back to the concrete port and interface names.

Example: examples/detect-interface-added.ts

Common OVS Workflows

These examples focus on patterns that show up often in virtualized environments, where OVS is used to connect VM or container networking to a virtual switch.

Create a Bridge With an Internal Interface

What this does:

  • creates an Interface row of type internal
  • creates a Port that owns that interface
  • creates a Bridge that owns that port

Why it is done this way:

  • in OVS, a bridge usually owns ports, and ports own interfaces
  • creating all three rows in one transaction keeps the change atomic
  • named UUIDs let later operations refer to rows inserted earlier in the same transaction

Example: examples/bridge-port-interface.ts

Attach a New Interface to an Existing Bridge

What this does:

  • creates a new Interface
  • creates a Port that references that interface
  • mutates the existing bridge so the new port is added to its ports set

Why this is a common pattern:

  • hypervisors and container hosts often attach new virtual NICs dynamically
  • mutating the bridge ports set avoids rewriting the whole bridge row
  • keeping it in one transaction prevents partial attachment state

Example: examples/attach-interface-to-bridge.ts

In practice, type: "internal" is useful when you want OVS itself to create the interface device. Leaving type unset is common when attaching an already existing device such as a tap interface created by a hypervisor.

Resource Management

The client implements AsyncDisposable, so it also works with await using in runtimes that support explicit resource management.

await using client = new OVSDBClient();
await client.connect();
const dbs = await client.listDbs();

Error Handling

  • Transport/request failures reject with Error
  • OVSDB JSON-RPC errors reject with OvsdbRpcError
  • malformed inbound frames emit protocolError
  • socket-level failures emit transportError

Documentation

Generate API docs with Typedoc:

npm run docs:build

The public API is documented with TSDoc so the generated output is usable as a reference, not just a symbol dump.

Roadmap

Planned work for the next iterations of the library:

  • relation-aware schema generation so UUID reference columns can emit stronger types such as PortRef or InterfaceRef instead of plain Uuid
  • richer codegen metadata for table relationships derived from refTable and refType
  • helper utilities for working with generated reference types in transactions and monitor snapshots
  • live TLS integration coverage for the transport and generator CLI
  • stricter runtime validation for inbound notifications and response payloads

The intended direction is to make the generator more relation-aware first, before attempting a larger ORM-style layer.

Development

npm test
npm run build
npm run docs:build

License

Apache-2.0. See LICENSE.