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

@vishwakarman-technology/bun-kv-sqlite

v1.0.1

Published

A fast, persistent Key-Value store for [Bun](https://bun.sh), backed by SQLite.

Readme

BunKV

A fast, persistent Key-Value store for Bun, backed by SQLite.

Features

  • Deno KV Compatible API: Familiar get, set, delete, list, and atomic methods.
  • Persistent or In-Memory: Use a file path for persistence or :memory: for ephemeral storage.
  • High Performance: Built on bun:sqlite with optimized query execution.
  • Binary & Complex Keys: Supports arbitrary complex keys (strings, numbers, booleans, Uint8Arrays) with correct lexicographical sorting.
  • Atomic Transactions: Supports multiple operations in a single atomic commit.
  • Expiration: Built-in TTL support (expireIn).

Installation

bun install @vishwakarman-technology/bunkv

Usage

Basic Operations

import { openKv } from "@vishwakarman-technology/bunkv";

const kv = await openKv("my-database.sqlite");

// Set a value
await kv.set(["users", "alice"], { name: "Alice", age: 30 });

// Get a value
const entry = await kv.get(["users", "alice"]);
console.log(entry.value); // { name: "Alice", age: 30 }

// Delete
await kv.delete(["users", "alice"]);

Listing Keys

List operations support prefixes and ranges.

await kv.set(["users", "alice"], "Alice");
await kv.set(["users", "bob"], "Bob");

// List all users
for await (const entry of kv.list({ prefix: ["users"] })) {
    console.log(entry.key, entry.value);
}

Expiration (TTL)

Automatically expire keys after a duration (in milliseconds).

// Expire in 10 seconds
await kv.set(["session", "123"], "active", { expireIn: 10_000 });

Watching Keys

Listen for changes on specific keys. The watch method returns a ReadableStream that emits the current values immediately and whenever they change.

const stream = kv.watch([
    ["users", "alice"],
    ["users", "bob"]
]);

// Iterate over the stream to handle updates
for await (const entries of stream) {
    const alice = entries[0];
    const bob = entries[1];
    
    console.log("Alice:", alice.value);
    console.log("Bob:", bob.value);
}

Atomic Transactions

Perform multiple operations atomically. Checks allow for optimistic concurrency control.

const result = await kv.atomic()
    .check(["bank", "alice"], currentVersion) // Optional optimistic check
    .set(["bank", "alice"], 100)
    .delete(["pending", "tx_1"])
    .commit();

if (result.ok) {
    console.log("Transaction succeeded", result.version);
} else {
    console.log("Transaction failed (check failed)");
}

OpenTelemetry Tracing

Enable OpenTelemetry tracing by setting the OTEL_BUN environment variable to true.

OTEL_BUN=true bun run index.ts

This will automatically instrument:

  • get, set, delete operations
  • atomic.commit transactions

Ensure you have a valid OpenTelemetry SDK setup in your application to capture these traces.

Error Handling

Common errors you might encounter:

  • "Check failed: key exists": During an atomic operation with a check(key, null), the key already existed.
  • "Check failed: version mismatch": The version specified in check(key, version) did not match the current database version.
  • "Unsupported key type: ...": You tried to use a key type that is not supported (e.g., Symbol, Function).

Benchmarks

Benchmarks run on Apple Silicon (M-Series).

In-Memory (:memory:)

Raw throughput without disk I/O overhead.

  • Writes: ~60,000 ops/sec
  • Reads: ~170,000 ops/sec
  • Mixed: ~110,000 ops/sec

Filesystem (db.sqlite)

Real-world persistent storage using SQLite WAL mode.

  • Writes: ~3,500 ops/sec
  • Reads: ~78,000 ops/sec
  • 10MB Write: ~15ms
  • 10MB Read: ~7ms

Bulk Insert Benchmark

Insertion of 1,000,000 user records (atomic batches of 1000).

  • Total Time: ~10.24s
  • Throughput: ~97,000 ops/sec (batched)
  • Database Size: ~262 MB

Limits

BunKV supports significantly larger limits than standard Deno KV (which often limits Values to 64KB).

| Feature | Tested Limit | Notes | |---------|--------------|-------| | Key Size | 10 KB+ | Standard Deno KV limit is 2KB. | | Value Size | 100 MB+ | Standard Deno KV limit is 64KB. Restricted mainly by system memory and SQLite row limits. |

License

MIT