pulkdb
v1.0.0
Published
A fast, type-safe JSON/YAML database for Node.js with a multi-file path system, dot-notation, TTL, encryption, events, and one-line migration to/from MongoDB (Mongoose), Firebase, QuickDB, croxydb, lowdb and more.
Maintainers
Readme
pulkdb
A fast, type-safe JSON / YAML database for Node.js — with a multi-file path system, dot-notation, TTL, encryption, events, and one-line migration to/from MongoDB (Mongoose), Firebase, QuickDB, croxydb and lowdb.
pulkdb is a modern rewrite of the idea behind croxydb:
a tiny file database you can set/get with dot-notation — but with far more
features, full TypeScript types, correct edge-case handling, crash-safe writes,
and a migration engine so your data is never locked in.
🇹🇷 Türkçe: pulkdb; dosya tabanlı (JSON/YAML), TypeScript ile yazılmış, çok dosyalı path sistemi olan modern bir veritabanıdır. Verilerinizi tek satırla mongoose, firebase, quickdb, croxydb gibi yerlere taşıyabilir veya oradan içeri aktarabilirsiniz.
data.json,user.json,commit.jsongibi verileri ayrı dosyalara bölmekdb.path("user")kadar kolaydır.
Install
npm install pulkdbZero required runtime dependencies. YAML, Mongoose, Firebase and QuickDB are optional — install them only if you use them.
npm install yaml # for the YAML driver
npm install mongoose # to migrate to/from MongoDB
npm install firebase-admin # to migrate to/from FirestoreQuick start
import { PulkDB } from "pulkdb";
const db = new PulkDB({ dir: "./database", file: "data" }); // -> ./database/data.json
db.set("user.name", "Ada"); // dot-notation, creates nested objects
db.get("user"); // { name: "Ada" }
db.get("user.name"); // "Ada"
db.set("score", 0); // ✅ 0, false and "" are valid (croxydb throws!)
db.add("score", 10); // 10
db.push("tags", "a", "b"); // ["a", "b"]
db.has("user.name"); // true
db.delete("user.name"); // truecroxydb-style drop-in (default instance):
import db from "pulkdb";
db.set("x.y.z", "abc"); // ./database/db.jsonWhy pulkdb over croxydb?
| | croxydb | pulkdb |
|---|---|---|
| Stores 0, false, "" | ❌ throws blankData | ✅ works |
| Multiple instances | ❌ global singleton | ✅ real instances |
| Multi-file path system | ⚠️ reconfigure globally | ✅ db.path("users") |
| TypeScript types | any | ✅ generics everywhere |
| Crash-safe writes | ❌ raw writeFileSync | ✅ atomic temp+rename |
| Caller aliasing bugs | ❌ mutates your refs | ✅ deep-cloned |
| Async API | ❌ sync only | ✅ sync and async |
| TTL / expiry | ❌ | ✅ set(k, v, { ttl }) |
| Encryption at rest | ❌ | ✅ AES-256-GCM |
| Events | ❌ | ✅ on("set" \| "delete" \| …) |
| Update check on every op | ❌ network call each call | ✅ none |
| Migration | ⚠️ 3 hard-coded helpers | ✅ pluggable engine |
The path system (multi-file)
Split your data into separate files — exactly the data.json / user.json /
commit.json separation you'd expect:
const db = new PulkDB({ dir: "./database" });
const users = db.path("users"); // ./database/users.json
const commits = db.path("commit"); // ./database/commit.json
users.set("42.name", "Ada");
commits.push("log", { sha: "abc123" });path() (aliases: table(), collection()) returns a real PulkDB instance,
memoized per name, with the same options as its parent.
Migration — never get locked in
One function, any direction. source and target can each be a PulkDB
instance or any built-in connector.
import { migrate, quickdbConnector, mongooseConnector } from "pulkdb";
// QuickDB ➜ pulkdb
await migrate(quickdbConnector(quick), db);
// pulkdb ➜ MongoDB (Mongoose)
await db.exportTo(mongooseConnector(KvModel));
// croxydb ➜ pulkdb
import { croxydbConnector } from "pulkdb";
await db.importFrom(croxydbConnector(require("croxydb")));
// pulkdb ➜ Firebase / Firestore
import { firebaseConnector } from "pulkdb";
await db.exportTo(firebaseConnector(admin.firestore(), "kv"));Built-in connectors: quickdbConnector, croxydbConnector, mongooseConnector,
firebaseConnector, lowdbConnector, jsonConnector. Each works as both a
source and a target. Options like transform, clearTarget and onProgress:
const report = await migrate(source, target, {
clearTarget: true,
transform: (e) => (e.key.startsWith("tmp_") ? null : e), // skip temp keys
onProgress: ({ done, total, key }) => console.log(`${done}/${total} ${key}`),
});
// report -> { source, target, migrated, skipped, durationMs }A PulkDB is itself a connector, so await from(dbA).to(dbB) just works.
croxydb-compatible shortcuts are also provided: db.move(quickdb),
db.moveToMongo(model), db.moveFromMongo(model).
TTL / expiry
db.set("session", token, { ttl: 60_000 }); // expires in 60s
db.ttl("session"); // remaining ms, or null
db.removeTtl("session"); // make permanent
db.sweep(); // purge all expired keys nowPass ttlSweepInterval to expire keys in the background.
Encryption at rest
const db = new PulkDB({ dir: "./secure", file: "vault", encryption: "my-pass" });
db.set("apiKey", "s3cr3t"); // file on disk is AES-256-GCM ciphertextStorage drivers
| Driver | Format | Notes |
|---|---|---|
| JSONDriver | .json | default |
| YAMLDriver | .yaml | requires yaml |
| MemoryDriver | — | in-process, great for tests |
Choose with format: "json" | "yaml" | "memory", or pass a custom driver
implementing the Driver interface.
Write modes
instant(default) — write after every change, crash-safe.debounced— coalesce a burst of writes (debounceMs).manual— only persist when you calldb.save()/db.saveAsync().
API overview
Core set get fetch has delete ensure update + *Async variants
Numbers add subtract multiply divide modulo inc dec math
Arrays push pull/unpush pop shift unshift splice setByIndex delByIndex
setByPriority delByPriority (croxydb-compatible, 1-based)
Query keys values entries all size type find filter some every map
startsWith includes
Manage rename copy clear/deleteAll snapshot reload close
TTL ttl removeTtl sweep
Persist save saveAsync
Paths path table collection
Migrate importFrom exportTo + move moveToMongo moveFromMongo (compat)
Events on/once/off("set"|"delete"|"change"|"clear"|"save"|"ready"|"error")Every method is fully typed; get<User>("user") returns User | undefined.
CLI
npx pulkdb --dir ./database --file data set user.name '"Ada"'
npx pulkdb --dir ./database --file data get user
npx pulkdb --dir ./database --file data export backup.jsonLicense
MIT © Pulkadot
