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

@forjajs/json-driver

v0.1.1

Published

A standalone, page-based B+tree JSON storage engine — usable with or without @forjajs/orm.

Readme

@forjajs/json-driver

A real, page-based B+tree JSON document storage engine — written from scratch in TypeScript, with zero dependencies. Usable on its own in any Node.js project, no Forja required.

Not a "load the whole file into memory" JSON store. It's a genuine storage engine: a Pager doing page-granular disk I/O (4096-byte pages, like SQLite), slotted pages for variable-length records, overflow pages for oversized documents, and an actual B+tree index for lookups and full scans.

Status: v1, functionally complete, not battle-tested

This is a from-scratch storage engine built as a deep dive into how real databases work under the hood — not a drop-in replacement for a production-grade embedded database. It's fully tested (round-trips, forced splits, concurrent access, tombstone deletion, overflow chains) and works correctly for everything it claims to do. What it deliberately does not have yet:

  • No write-ahead log / crash recovery. A crash mid-write can leave the file in an inconsistent state. flush() runs after every top-level operation, but that's best-effort durability, not ACID.
  • No multi-process locking. The in-process AsyncMutex serializes every call within one Node process — it does nothing for two processes touching the same file.
  • No secondary indexes. findOne/scan do a full leaf-chain traversal with an in-memory predicate filter. Fine for small/medium datasets, not built for large-scale querying.
  • No full B-tree rebalancing. Deletes reclaim space via tombstone compaction and free completely-empty leaves, but never merge underfull neighboring pages.

If you need any of the above, reach for something mature (LevelDB, SQLite via better-sqlite3, etc). This exists to be a real, understandable, hackable engine — not to compete with them.

Install

npm install @forjajs/json-driver

Usage

import { openDatabase } from "@forjajs/json-driver";

const db = await openDatabase("./data/users.db");

await db.set("user-1", { name: "Ada", role: "admin" });

const user = await db.get("user-1"); // { name: "Ada", role: "admin" }
const exists = await db.has("user-1"); // true

const admins = await db.scan((doc) => doc.role === "admin");

await db.delete("user-1");
await db.close();

API

interface JsonEngineOptions {
  pageSize?: number; // default 4096
}

interface JsonDatabase {
  get(id: string): Promise<Record<string, unknown> | null>;
  set(id: string, doc: Record<string, unknown>): Promise<void>; // upsert
  has(id: string): Promise<boolean>;
  delete(id: string): Promise<void>;
  scan(
    predicate?: (doc: Record<string, unknown>, id: string) => boolean,
  ): Promise<Array<Record<string, unknown>>>;
  close(): Promise<void>;
}

function openDatabase(filePath: string, options?: JsonEngineOptions): Promise<JsonDatabase>;

Every call is serialized through an internal mutex — concurrent calls are safe within one process, reads included.

How it's built

See PLAN-json-engine.md in the main Forja repo for the full design: on-disk page format, B+tree cell layout, the free-list, overflow chains, and the milestone-by-milestone build log.

License

MIT