LATEST RELEASE v3.1.0

DOCS.

The definitive guide to json-database-st. High-performance, transactional, and type-safe data persistence for Node.js.

Installation

npm install json-database-st lodash proper-lockfile

Quick Start

Initialize the database. If the file doesn't exist, it will be created automatically.

const JSONDatabase = require('json-database-st');

// Initialize (Auto-creates file if missing)
const db = new JSONDatabase('db.json');

// Write
await db.set('user.1', { name: 'Alice', role: 'admin' });

// Read
const user = await db.get('user.1');

Hybrid Architecture

v3 offers two storage consistency modes. Choose based on your durability needs.

MODE: DURABLE

Writes are appended to a WAL file immediately. Crash-safe.

new JSONDatabase('db', { 
  wal: true 
})
MODE: IN-MEMORY

Max throughput (~90k ops/sec). Writes update RAM instantly, disk periodically.

new JSONDatabase('db', { 
  wal: false 
})

Basic Operations

set(path, value)

Writes data. Creates nested paths automatically.

await db.set('config.theme', 'dark');
await db.set('users.1.settings.notifications', true);

get(path, defaultValue?)

Retrieves data. Returns `defaultValue` if path doesn't exist.

const val = await db.get('config.theme', 'light');

has(path)

Checks existence. High performance.

if (await db.has('users.1')) { ... }

Delete

delete(path)

Removes a key or object property.

await db.delete('users.1.settings'); // Delete nested property
await db.delete('users.1');          // Delete entire object

Arrays

push(path, ...items)

Adds items to an array. Dedupes automatically.

await db.push('users.1.tags', 'premium', 'beta');

pull(path, ...items)

Removes items from an array (deep equality).

await db.pull('users.1.tags', 'beta');

Math

add(path, amount)

Atomic increment.

await db.add('users.1.loginCount', 1);

subtract(path, amount)

Atomic decrement.

await db.subtract('users.1.credits', 50);

Indices (Fast Lookups)

Define indices in the constructor for O(1) read performance.

const db = new JSONDatabase('db.json', {
    indices: [{ name: 'email', path: 'users', field: 'email' }]
});

// Instant Lookup
const user = await db.findByIndex('email', 'alice@corp.com');

Advanced Query Cursor

Chainable query builder for filtering, sorting, and selecting fields.

const results = await db.query('users')
    .limit(10)
    .skip(0)
    .sort({ age: -1 }) // Descending
    .select(['id', 'name', 'email'])
    .exec();

Find (Legacy)

Simple scan operation. Useful for small datasets or ad-hoc queries.

const user = await db.find('users', u => u.age > 18);
// OR
const user = await db.find('users', { role: 'admin' });

Paginate

Helper for API endpoints.

const page = await db.paginate('users', 1, 20);
// Returns: { data: [...], meta: { total, pages, ... } }

Batch Operations

Execute multiple writes in a single IO tick. Extremely fast.

await db.batch([
    { type: 'set', path: 'logs.1', value: 'log data' },
    { type: 'delete', path: 'temp.cache' }
]);

Transactions

Atomic read-modify-write. The database is locked during execution.

await db.transaction(async (data) => {
    if (data.bank.balance >= 100) {
        data.bank.balance -= 100;
        data.users.1.wallet += 100;
    }
    // Returns modified state automatically
    return data;
});

Snapshots

Create a backup of the current state.

const backupPath = await db.createSnapshot('daily');
console.log('Backup saved to:', backupPath);

Middleware

Intercept operations before they happen.

db.before('set', 'users.*', (ctx) => {
    ctx.value.updatedAt = Date.now();
    return ctx;
});