btrdb is a persistent, embedded NoSQL database engine written in TypeScript. It features a B-tree Copy-on-Write (CoW) architecture inspired by btrfs, enabling high-performance reads, crash safety, and instant point-in-time snapshots.
- Universal Runtime: Runs on Deno (native) and Node.js.
- Hybrid Storage: Supports both Key-Value sets and Document sets in the same database.
- Copy-on-Write (CoW): Never overwrites data. Ensures database integrity and enables instant snapshots.
- Time Travel: Create named snapshots and read data from any previous point in time.
- Advanced Querying: SQL-like tagged template queries or functional query builders.
- Efficient Indexing: Support for unique, compound, and computed indices.
- Transactions: ACID compliance with concurrent reader isolation.
- btrdbfs: Includes a FUSE filesystem implementation (mount your DB as a folder!).
⚠️ Warning: This project is under heavy development. The on-disk format and APIs are subject to change. Do not use in critical production environments yet.
Import directly from deno.land:
import{Database}from"https://deno.land/x/btrdb/mod.ts";Install via NPM:
npm install @yuuza/btrdbImport in your project:
import{Database}from"@yuuza/btrdb";// or const { Database } = require("@yuuza/btrdb");import{Database}from"https://deno.land/x/btrdb/mod.ts";// or @yuuza/btrdb// 1. Open database (creates file if not exists)constdb=newDatabase();awaitdb.openFile("data.db");// 2. Create a Document Setconstusers=awaitdb.createSet("users","doc");// 3. Insert Dataawaitusers.insert({username: "yuuza",role: "admin",active: true});awaitusers.insert({username: "guest",role: "visitor",active: false});// 4. Commit changes to diskawaitdb.commit();// 5. Query Dataconstadmin=awaitusers.query(query`role == ${"admin"}`);console.log(admin);db.close();Simple, persistent string-to-value storage.
constconfig=awaitdb.createSet("config","kv");// 'kv' is default if omitted// Set valuesawaitconfig.set("theme","dark");awaitconfig.set("max_connections",100);// Get valuesconsttheme=awaitconfig.get("theme");// "dark"// Iterateawaitconfig.forEach((key,val)=>{console.log(`${key}: ${val}`);});Store JSON-like objects with automatic IDs and powerful indexing.
interfaceUser{id: number;username: string;email: string;age: number;}constusers=awaitdb.createSet<User>("users","doc");// Define Indices (Critical for query performance)awaitusers.useIndexes({// Simple indexage: (u)=>u.age,// Unique indexusername: {unique: true,key: (u)=>u.username},// Computed/Compound indexactive_adult: (u)=>u.age>=18&&u.active,});// Upsert (Insert or Update by ID)awaitusers.upsert({id: 1,username: "john",email: "john@test.com",age: 30});btrdb provides a safe, tagged template literal syntax for queries.
Operators:==, !=, >, <, <=, >=, AND, OR, NOT, SKIP, LIMIT.
import{query}from"@yuuza/btrdb";// Find users older than 20 excluding specific IDsconstresults=awaitusers.query(query` age > ${20} AND NOT id == ${1} LIMIT ${10}`);// You can also use functional buildersimport{AND,EQ,GT}from"@yuuza/btrdb";constresults2=awaitusers.query(AND(GT("age",20),EQ("active",true)));Transactions guarantee atomicity. If an error occurs, changes are rolled back.
awaitdb.runTransaction(async()=>{constbank=awaitdb.getSet("bank","kv");constbalance=awaitbank.get("user_1");if(balance<100)thrownewError("Insufficient funds");awaitbank.set("user_1",balance-100);awaitbank.set("user_2",(awaitbank.get("user_2"))+100);});// Automatically commits here if successfulBecause btrdb is Copy-on-Write, creating snapshots is instant and cheap.
// 1. Commit current stateawaitdb.commit();// 2. Create a named snapshotawaitdb.createSnapshot("backup_v1");// 3. Make destructive changesawaitusers.delete(1);awaitdb.commit();// 4. Time Travel: Access the old dataconstsnapshot=awaitdb.getSnapshot("backup_v1");constoldUsers=snapshot.getSet("users","doc");console.log(awaitoldUsers.get(1));// The user still exists here!You can mount a btrdb database as a real folder on Linux/macOS using FUSE. See btrdbfs/README.md for details.
# Install CLI
npm install -g @yuuza/btrdbfs
# Mount database
btrdbfs my_data.db ./mountpointbtrdb includes a basic HTTP server for remote access.
import{HttpApiServer}from"@yuuza/btrdb";// ... open db ...newHttpApiServer(db).serve(Deno.listen({port: 1234}));btrdb uses a B-tree Copy-on-Write structure.
- Pages: Data is stored in fixed-size pages (default 4KB).
- Immutability: When a page is modified, it is not overwritten. Instead, it is copied to a new location, modified there, and the parent node is updated to point to the new address.
- Root Tree: This bubble-up effect reaches the "SuperPage" (Root). By keeping a reference to an old Root address, you effectively have a snapshot of the entire database at that moment.
MIT License.