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

@shortsqueeze/thunderstrike

v0.1.3

Published

Node.js client for the thunderstrike key-value database (TLS 1.3, pipelined, prebuilt native addon)

Readme

@shortsqueeze/thunderstrike

Node.js client for the thunderstrike key-value database: a pool of pipelined TLS 1.3 connections, with a Promise for every operation. Nothing blocks the event loop.

The client is a prebuilt native addon. npm installs the one for your platform as an optional dependency (@shortsqueeze/thunderstrike-<platform>-<arch>); there is no build step and no compiler needed. TypeScript types are included.

Install

npm install @shortsqueeze/thunderstrike

Node.js 16 or newer, on Linux x64 / arm64 (glibc 2.17 or newer) or Windows x64. macOS comes in a later release. Do not install with --omit=optional / --no-optional: that skips the addon.

Quick start

The server speaks TLS 1.3 only. The client needs the CA certificate that issued the server's certificate (docker/tls/ca.crt in the server's kit) and a DNS name that certificate carries (localhost unless the server was set up with other THUNDERSTRIKE_TLS_NAMES).

// ES module (top-level await). With require():
//   const { ThunderstrikeClient } = require("@shortsqueeze/thunderstrike");
import { ThunderstrikeClient } from "@shortsqueeze/thunderstrike";
import { readFileSync } from "node:fs";

const db = await ThunderstrikeClient.connect({
  endpoints: ["127.0.0.1:7380"],
  tlsServerName: "localhost",
  tlsCaPem: readFileSync("ca.crt"),
});

await db.set(Buffer.from("user:1"), Buffer.from("ada"));
const v = await db.get(Buffer.from("user:1"));   // Buffer, or null on a miss
console.log(v?.toString());                      // "ada"

db.close();

Give it one address. The client asks that server for the cluster layout and connects to every core (core c listens on port 7380 + c), so those ports must be reachable too. connect resolves only once every connection, TLS included, is up, so a wrong address or a certificate that does not verify rejects there rather than on first use.

tlsServerName is sent as SNI and checked against the certificate, so it is the name the certificate was issued for, not necessarily the host you dial. There is no way to turn verification off.

Operations

Keys and values are Buffers; the *String variants take and return UTF-8 text. A key is at most 65,535 bytes; an empty value is refused. Keys do not expire: a value stays until it is deleted or overwritten.

const k = Buffer.from("k");

await db.set(k, Buffer.from("v"));
await db.get(k);                          // Buffer | null
await db.setString("greeting", "hello");
await db.getString("greeting");           // "hello" | null
await db.exists(k);                       // true / false
await db.append(k, Buffer.from("-more")); // appends (creates if absent); resolves to the new length
await db.delete(k);                       // true if it was there
await db.ping();

Batches

For more than one key, use the batch calls rather than Promise.all over single calls: every request goes on the wire before any answer is awaited, in one trip across the JS/native boundary.

const keys = ["a", "b", "missing"].map((s) => Buffer.from(s));

await db.setMany(keys.slice(0, 2), [Buffer.from("1"), Buffer.from("2")]);
await db.getMany(keys);      // [<Buffer 31>, <Buffer 32>, null]
await db.deleteMany(keys);   // [true, true, false]

One client per process is the intended shape: it is a connection pool, and every method may be called concurrently.

Errors and retries

Every rejection is an Error carrying:

  • thunderstrikeCode: the numeric status (positive from the server, negative from the client). Compare with codes, e.g. codes.BUSY.
  • retryClass: whether sending the request again is sound.
  • busy: true when the server answered Busy.

| retryClass | meaning | |---|---| | RETRY_ALWAYS | Busy: the server did not apply it. Retry anything after a short backoff. | | RETRY_IF_IDEMPOTENT | A lost connection or a timeout: the outcome is unknown. Repeat get, set, exists and ping only. | | RETRY_NEVER | Everything else. |

The client has already retried Busy answers (every operation but delete) and dropped connections (idempotent operations) before it rejects.

import { codes, RETRY_ALWAYS, describe } from "@shortsqueeze/thunderstrike";

try {
  await db.set(k, v);
} catch (e) {
  if (e.retryClass === RETRY_ALWAYS) { /* not applied; try again later */ }
  console.error(e.thunderstrikeCode, describe(e.thunderstrikeCode), e.message);
}

Configuration

Options to ThunderstrikeClient.connect, all optional except the endpoint and (against the real server) the TLS pair:

| option | meaning | |---|---| | endpoints | Bootstrap addresses. One is enough. | | tlsServerName, tlsCaPem | TLS 1.3: the certificate's name and the CA (PEM, string or Buffer). Give both. | | tlsClientCertPem, tlsClientKeyPem | Client certificate (mTLS), for a server that requires one. | | requestTimeoutMs | Per-request deadline, covering retries. Default 60000; 0 disables it. | | connectTimeoutMs | Connect and TLS handshake deadline. | | connectionsPerEndpoint | TCP connections per server core. | | maxInflight | Pipeline depth per connection. | | maxRetries | Retries for an idempotent request whose connection dropped. | | busyRetries, busyBackoffMinMs, busyBackoffMaxMs, busyRetryWindowMs | Busy retry policy. Defaults 4, 2, 200, 5000. | | maxResponseBytes | Largest response the client will accept. |

db.stats() returns pool counters (connections, requests, bytes, retries). db.endpoints() is the number of server cores connected, db.shards() the number of shards. version() is the client's version.

Links

  • Source and issues: https://github.com/TheManhattanProject/thunderstrike-client
  • Server image: https://hub.docker.com/r/sbansal793/thunderstrike
  • Clients for other languages: see the repository README.

License

Proprietary, free to use: see the LICENSE file in the package. You may build this library into your own applications and ship it as part of them.

Copyright (c) 2026 SHORTSQUEEZE PRIVATE LIMITED.