Tiny local JSON database for Node, Electron and the browser
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Core async and sync database classes that manage data with configurable storage adapters. These classes provide the fundamental database operations and serve as the foundation for all lowdb functionality.
Main asynchronous database class for managing data with async adapters.
/**
* Asynchronous database class for managing data with async storage adapters
* @template T - The type of data stored in the database
*/
class Low<T = unknown> {
constructor(adapter: Adapter<T>, defaultData: T);
/** Storage adapter instance */
adapter: Adapter<T>;
/** Current database data */
data: T;
/** Load data from adapter to memory */
read(): Promise<void>;
/** Save current data to adapter */
write(): Promise<void>;
/** Update data using a function and save automatically */
update(fn: (data: T) => unknown): Promise<void>;
}Usage Examples:
import { Low } from "lowdb";
import { JSONFile } from "lowdb/node";
type Data = {
users: Array<{ id: number; name: string }>;
settings: { theme: string };
};
const defaultData: Data = { users: [], settings: { theme: "light" } };
const adapter = new JSONFile<Data>("db.json");
const db = new Low<Data>(adapter, defaultData);
// Initialize database
await db.read();
// Direct data manipulation
db.data.users.push({ id: 1, name: "Alice" });
db.data.settings.theme = "dark";
await db.write();
// Update with automatic save
await db.update((data) => {
data.users.push({ id: 2, name: "Bob" });
data.settings.theme = "blue";
});Synchronous database class for managing data with sync adapters.
/**
* Synchronous database class for managing data with sync storage adapters
* @template T - The type of data stored in the database
*/
class LowSync<T = unknown> {
constructor(adapter: SyncAdapter<T>, defaultData: T);
/** Storage adapter instance */
adapter: SyncAdapter<T>;
/** Current database data */
data: T;
/** Load data from adapter to memory synchronously */
read(): void;
/** Save current data to adapter synchronously */
write(): void;
/** Update data using a function and save automatically */
update(fn: (data: T) => unknown): void;
}Usage Examples:
import { LowSync } from "lowdb";
import { JSONFileSync } from "lowdb/node";
type Data = {
posts: Array<{ id: number; title: string; views: number }>;
};
const defaultData: Data = { posts: [] };
const adapter = new JSONFileSync<Data>("posts.json");
const db = new LowSync<Data>(adapter, defaultData);
// Initialize database
db.read();
// Synchronous operations
db.data.posts.push({ id: 1, title: "Hello World", views: 0 });
db.write();
// Update with automatic save
db.update((data) => {
const post = data.posts.find(p => p.id === 1);
if (post) post.views++;
});Interface for asynchronous storage adapters.
/**
* Interface for asynchronous storage adapters
* @template T - The type of data handled by the adapter
*/
interface Adapter<T> {
/** Read data from storage, returns null if no data exists */
read(): Promise<T | null>;
/** Write data to storage */
write(data: T): Promise<void>;
}Interface for synchronous storage adapters.
/**
* Interface for synchronous storage adapters
* @template T - The type of data handled by the adapter
*/
interface SyncAdapter<T> {
/** Read data from storage synchronously, returns null if no data exists */
read(): T | null;
/** Write data to storage synchronously */
write(data: T): void;
}In-memory storage adapters for testing and temporary data storage.
/**
* In-memory async adapter for testing and temporary storage
* @template T - The type of data stored
*/
class Memory<T> implements Adapter<T> {
constructor();
read(): Promise<T | null>;
write(obj: T): Promise<void>;
}
/**
* In-memory sync adapter for testing and temporary storage
* @template T - The type of data stored
*/
class MemorySync<T> implements SyncAdapter<T> {
constructor();
read(): T | null;
write(obj: T): void;
}Usage Examples:
import { Low, LowSync, Memory, MemorySync } from "lowdb";
// Async memory adapter
const asyncDb = new Low(new Memory<{ count: number }>(), { count: 0 });
await asyncDb.read();
asyncDb.data.count = 42;
await asyncDb.write();
// Sync memory adapter
const syncDb = new LowSync(new MemorySync<string[]>(), []);
syncDb.read();
syncDb.data.push("hello", "world");
syncDb.write();
// Memory adapters are automatically used in test environments
// when using presets, providing isolated test dataAccess and modify db.data directly, then call write() to persist:
db.data.posts.push({ id: 1, title: "New Post" });
db.data.settings.theme = "dark";
await db.write(); // or db.write() for syncUse the update() method for atomic operations:
await db.update((data) => {
data.posts.push({ id: 1, title: "New Post" });
data.settings.theme = "dark";
}); // Automatically saves after function executionUse JavaScript's native Array methods for querying:
const { posts } = db.data;
// Find operations
const post = posts.find(p => p.id === 1);
const activePosts = posts.filter(p => p.active);
// Sorting and manipulation
const sortedPosts = posts.toSorted((a, b) => b.views - a.views);
const firstPost = posts.at(0);
const lastPost = posts.at(-1);
// Iteration
posts.forEach(post => console.log(post.title));
const titles = posts.map(post => post.title);The core classes handle adapter-level errors by propagating them to the caller:
try {
await db.read();
} catch (error) {
console.error("Failed to read database:", error);
}
try {
await db.write();
} catch (error) {
console.error("Failed to write database:", error);
}lowdb provides full TypeScript support with generic type preservation:
type UserData = {
users: Array<{ id: number; name: string; email: string }>;
meta: { version: number; lastUpdated: Date };
};
const db = new Low<UserData>(adapter, defaultData);
// TypeScript will provide full intellisense and type checking
db.data.users.push({ id: 1, name: "Alice", email: "alice@example.com" }); // ✅
db.data.users.push({ id: 2, name: "Bob" }); // ❌ TypeScript error: missing email
db.data.meta.version = "1.0"; // ❌ TypeScript error: version should be number