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

@stefanak-michal/bolt-protocol

v1.1.1

Published

Low-level JavaScript/TypeScript Bolt protocol driver for Neo4j and other Bolt-compatible graph databases

Readme

Bolt protocol js driver

JavaScript/TypeScript library for communication with graph databases over WebSocket using the Bolt protocol specification. Bolt protocol was created by Neo4j and documentation is available at https://www.neo4j.com/docs/bolt/current/. This library is aimed to be low level, support all available versions and keep up with protocol messages architecture and specifications.

ko-fi

NPM Version GitHub commits since latest release NPM Downloads

:warning: This project was made as alternative for Neo4j official library which by how it's structured is vendor-locked without support for older bolt versions.

:label: Version support

This library supports Bolt <= 6.

:books: Supported ecosystems

This library doesn't guarantee that each ecosystem has Bolt protocol implemented correctly.

:white_check_mark: Requirements

  • Node.js 18+
  • TypeScript 5+ (if using TypeScript)

:floppy_disk: Installation

Within your node.js project use following command:

npm install @stefanak-michal/bolt-protocol

Or in your website include following code:

<script src="https://cdn.jsdelivr.net/npm/@stefanak-michal/bolt-protocol@1"></script>

:desktop_computer: Usage

Concept of usage is based on Bolt messages. Bolt messages are mapped 1:1 as protocol methods. Available protocol methods depend on the Bolt version. Communication works in pipeline and you can chain multiple Bolt messages before consuming responses from the server.

The main Bolt class handles the initial handshake and returns the appropriate protocol version instance. Basic usage consists of query execution and fetching responses split in two methods. First message run is for sending queries. Second message pull is for fetching the response from the executed query. The response for pull always contains n+1 rows because the last entry is a success message with meta information.

:information_source: More info about available Bolt messages: https://www.neo4j.com/docs/bolt/current/bolt/message/

Available methods

Bolt class

| Method | Description | Return | | -------------- | ----------------------------------------------------------------------------------------------------- | ----------- | | Bolt.connect | Static factory. Creates a connection, executes the handshake and returns a protocol version instance. | AProtocol |

Protocol class

| Method | Description | | -------------- | ----------------------------------------------------- | | hello | Initialize connection with the server | | logon | Authenticate the user (Bolt 5.1+) | | logoff | Log out the authenticated user (Bolt 5.1+) | | run | Execute a query. Response contains meta information. | | pull | Pull results from an executed query | | discard | Discard results waiting for pull | | begin | Start a transaction | | commit | Commit the current transaction | | rollback | Rollback the current transaction | | reset | Reset the connection state | | route | Fetch cluster routing information | | telemetry | Send telemetry data (Bolt 5.4+) | | getResponse | Await and return the next pending server response | | getResponses | Async generator yielding all pending server responses | | | | | init | @see hello (Bolt 1/2) | | pullAll | @see pull (Bolt 1/2) | | discardAll | @see discard (Bolt 1/2) |

Multiple methods accept an extra argument. This argument can contain any key-value pairs defined by the Bolt specification. The content of extra changed across Neo4j versions — check the Bolt documentation for the specific version you are working with.

Authentication

logon (Bolt 5.1+) and hello (Bolt < 5.1) both accept an auth object. The object must contain a scheme key and optionally principal and credentials depending on the chosen scheme.

| scheme | principal | credentials | | ---------- | --------- | ----------- | | none | | | | basic | username | password | | bearer | | token | | kerberos | | token |

Transactions

Bolt from version 3 supports explicit transactions via the following methods:

  • begin
  • commit
  • rollback

run executes a query in an auto-commit transaction if no explicit transaction is open.

Example

import { Bolt, WebSocketChannel } from 'bolt.js';

// Create a connection
const conn = new WebSocketChannel();

// Connect and negotiate the protocol version
const protocol = await Bolt.connect(conn, '127.0.0.1', 7687);

// Initialize connection with the server
let response = await protocol.hello({ user_agent: 'my-app/1.0' });
// verify response for successful initialization

// Authenticate (Bolt 5.1+)
response = await protocol.logon({ scheme: 'basic', principal: 'neo4j', credentials: 'neo4j' });
// verify response for successful login

// Pipeline two messages: execute a query with parameters, then pull records
protocol.run('RETURN $a AS num, $b AS str', { a: 123, b: 'text' });
protocol.pull();

// Consume all pending server responses
for await (const resp of protocol.getResponses()) {
    // resp is an instance of Response
    // First response:  SUCCESS for RUN
    // Second response: RECORD for PULL (one per row)
    // Third response:  SUCCESS for PULL
    if (resp.isRecord) {
        console.log(resp.content);
    }
}

:package: Bundle usage

The library is also available as a pre-built UMD bundle:

<script src="dist/bolt.js"></script>
<script>
    const { Bolt, WebSocketChannel } = BoltDriver;
</script>

:busts_in_silhouette: Client helper class

The library includes a high-level Client helper class for simplified interaction with a graph database. It wraps common operations (authentication, queries, and transactions) so you don't have to manage protocol messages and responses manually.

Constructor

new Client(protocol: AProtocol)

Methods

| Method | Description | Return | | ------------------------------------ | ----------------------------------------------------------- | ----------------------------------------- | | login(auth: AuthToken) | Authenticate. Automatically adapts to the protocol version. | Promise<Response \| Response[] \| void> | | logout() | Log out (Bolt 5.1+). | Promise<Response> | | query(cypher, parameters?, extra?) | Execute a query and return all rows as arrays of values. | Promise<Record<string, unknown>[]> | | beginTransaction(extra?) | Begin a transaction. | Promise<Response> | | commit() | Commit the current transaction. | Promise<Response> | | rollback() | Rollback the current transaction. | Promise<Response> |

Example

import { Bolt, WebSocketChannel, Client } from 'bolt.js';

const conn = new WebSocketChannel();
const protocol = await Bolt.connect(conn, '127.0.0.1', 7687);

const client = new Client(protocol);
await client.login({ scheme: 'basic', principal: 'neo4j', credentials: 'neo4j' });

// Returns all rows as arrays keyed by field name
const rows = await client.query('MATCH (n:Person) RETURN n.name AS name, n.age AS age');
// rows = [{ name: 'Alice', age: 30 }, { name: 'Bob', age: 25 }]

// Transaction example
await client.beginTransaction();
await client.query('CREATE (n:Person {name: $name})', { name: 'Charlie' });
await client.commit(); // or client.rollback()

:chains: Connection

Bolt.connect accepts a connection object that implements IConnection. The library provides one built-in implementation.

WebSocketChannel

Uses the WebSocket protocol, which makes it compatible with browsers as well as Node.js. It handles Bolt message framing (chunking and dechunking) internally.

const conn = new WebSocketChannel();
const protocol = await Bolt.connect(conn, 'localhost', 7687);

Bolt.connect can also be called with no arguments. It defaults to WebSocketChannel, host 127.0.0.1 and port 7687:

const protocol = await Bolt.connect();

Encrypted connections

Pass true as the fourth argument to Bolt.connect to enable TLS:

const protocol = await Bolt.connect(conn, 'mydb.databases.neo4j.io', 7687, true);

:vertical_traffic_light: Server state

Server state is not reported by the server but is derived from received responses. You can access the current state through protocol.serverState. The property is updated with every getResponse / getResponses call.

:bar_chart: Cypher type mapping

| Neo4j | JavaScript | | ------------------- | ---------------------------------------------- | | Null | null | | Boolean | boolean | | Integer | number or BigInt | | Float | number | | String | string | | List | Array | | Dictionary | plain object | | Node | Node structure class | | Relationship | Relationship structure class | | UnboundRelationship | UnboundRelationship structure class | | Path | Path structure class | | Date / Time etc. | Temporal structure classes (Date, Time, …) | | Point | Point2D / Point3D structure classes | | Vector (Bolt 6) | Vector structure class |

Integer vs Float

JavaScript has a single number type, so the library infers the Bolt type automatically: a number with no decimal part is sent as Integer, a number with a decimal part is sent as Float.

When you need to override this — for example, sending 5 as a Float or truncating 3.9 to an Integer — wrap the value in the provided helper classes:

import { Integer, Float } from '@stefanak-michal/bolt-protocol';

// Sent as Bolt Float even though the value has no decimal part
protocol.run('CREATE (n:Node {x: $x})', { x: new Float(5) });

// Sent as Bolt Integer — decimal part is truncated
protocol.run('CREATE (n:Node {count: $count})', { count: new Integer(3.9) });

These wrappers work anywhere a value is accepted: query parameters, list elements, dictionary values, and nested structures.