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.
Writes are appended to a WAL file immediately. Crash-safe.
new JSONDatabase('db', {
wal: true
})
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;
});