lowdb Local JSON Database
lowdb is a lightweight, type-safe, local JSON database designed for Node.js, Electron, and browser environments. The current stable version is 7.0.1, with a frequent release cadence that has seen multiple major and minor versions released recently, indicating active development and continuous improvement. Key differentiators include its minimalist API for interacting with data using native JavaScript array methods, robust TypeScript support for data schema, and a highly extensible architecture via 'adapters'. These adapters allow for custom storage solutions (e.g., YAML, JSON5, encryption) and seamless integration across different environments (file system for Node, localStorage or sessionStorage for browsers). It is primarily an ESM-first package, simplifying usage in modern JavaScript projects but requiring specific import patterns. It also offers convenient presets for common use cases like JSON files and browser storage, alongside automatic in-memory mode for testing.
Common errors
-
SyntaxError: Cannot use import statement outside a module
cause Attempting to use `import` statements in a CommonJS context for an ESM-only package.fixConfigure your project to use ES Modules. In Node.js, add `"type": "module"` to your `package.json` or rename your files to `.mjs`. If using TypeScript, ensure your `tsconfig.json` targets an appropriate module system like `"module": "NodeNext"` or `"ESNext"`. -
TypeError: The 'defaultData' parameter is required for Low and LowSync constructors.
cause Missing the `defaultData` argument when instantiating `Low` or `LowSync`.fixProvide a default data object as the second argument: `new Low(adapter, { posts: [] })`. -
Error: Cannot find module 'lowdb/JSONFile' or 'lowdb/LocalStorage'
cause Incorrect import path for Node.js or browser adapters after the v5.0.0 split.fixFor Node.js, use `import { JSONFile } from 'lowdb/node'`. For browsers, use `import { LocalStorage } from 'lowdb/browser'`. -
Property 'someProperty' does not exist on type '{ posts: any[]; }' (or similar TypeScript error when accessing `db.data`)cause TypeScript compiler cannot infer the correct type of `db.data` without generic type parameters or proper default data definition.fixWhen initializing, provide a generic type to `JSONFilePreset` or `Low` to strongly type your data: `await JSONFilePreset<MyDataType>('db.json', defaultData)` or `new Low<MyDataType>(adapter, defaultData)`.
Warnings
- breaking The `JSONPreset` was superseded by `JSONFilePreset` in v7.0.0 for Node.js file storage. While `JSONPreset` might still work, `JSONFilePreset` is the recommended and future-proof way to initialize a database for JSON files.
- breaking Node.js 14 support was dropped with the release of v6.0.0. Additionally, Node.js >=18 is now explicitly required for `lowdb` v7.0.0 and above. Running on older Node versions will result in errors.
- breaking Since v6.0.0, the `Low` and `LowSync` constructors strictly require a `defaultData` parameter. This change improves TypeScript experience and prevents `db.data` from being `null` or `undefined`.
- breaking Beginning with v5.0.0, Node.js and browser-specific adapters were split into subpath imports. Node adapters like `JSONFile` are now found under `lowdb/node`, and browser adapters like `LocalStorage` under `lowdb/browser`.
- gotcha lowdb has been an ESM-only package since v3.0.0. Attempting to use CommonJS `require()` syntax will result in a `SyntaxError: Cannot use import statement outside a module`.
- gotcha When modifying `db.data` directly (e.g., `db.data.posts.push(item)`), the changes are not automatically persisted to the storage. You must explicitly call `await db.write()` to save these changes. The `db.update()` method handles writing automatically.
Install
-
npm install lowdb -
yarn add lowdb -
pnpm add lowdb
Imports
- JSONFilePreset
import { JSONFilePreset } from 'lowdb'import { JSONFilePreset } from 'lowdb/node' - Low
const { Low } = require('lowdb')import { Low } from 'lowdb' - LocalStoragePreset
import { LocalStoragePreset } from 'lowdb'import { LocalStoragePreset } from 'lowdb/browser' - JSONPreset (deprecated)
import { JSONPreset } from 'lowdb/node'import { JSONFilePreset } from 'lowdb/node'
Quickstart
import { JSONFilePreset } from 'lowdb/node';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
// Resolve __dirname equivalent in ESM
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const dbFilePath = join(__dirname, 'db.json');
type Post = { id: number; title: string; views: number };
type Data = { posts: Post[] };
async function runDbExample() {
// Define default data with type safety
const defaultData: Data = { posts: [] };
// Initialize the database with a JSON file adapter
// This will create 'db.json' if it doesn't exist, populated with defaultData
const db = await JSONFilePreset<Data>(dbFilePath, defaultData);
// Read the current data from the file
await db.read();
console.log('Initial data:', db.data);
// Add a new post using db.update() for atomic writes and automatic saving
const newPost = { id: 1, title: 'lowdb is awesome', views: 100 };
await db.update(({ posts }) => posts.push(newPost));
console.log('Data after adding post:', db.data);
// Query data using native JavaScript array methods
const { posts } = db.data;
const firstPost = posts.at(0);
console.log('First post:', firstPost);
// Modify an existing item and explicitly save
if (firstPost) {
firstPost.views += 10; // Modify in memory
console.log('Modified post in memory:', firstPost);
await db.write(); // Explicitly write changes back to db.json
}
console.log('Final data after explicit write:', db.data);
}
runDbExample().catch(console.error);