Classic LevelDB Database
classic-level is an `abstract-level` compliant database implementation backed by LevelDB, serving as the successor to `leveldown`. It offers features such as built-in encodings, sublevels, events, hooks, and first-class support for `Uint8Array`. The current stable version is 3.0.0, with a release cadence that has seen several minor and major updates in the past year, indicating active maintenance. Key differentiators include its adherence to the `abstract-level` interface, providing a consistent API across various Level-family databases, and its direct use of the battle-tested LevelDB C++ library for high performance. It also ships with TypeScript type definitions, making it suitable for modern JavaScript and TypeScript projects. It supports Node.js versions >=18 and Electron >=30, providing prebuilt binaries for common platforms.
Common errors
-
Error: IO error: While lock file: /path/to/db/LOCK: Resource temporarily unavailable
cause Another process or `ClassicLevel` instance is currently holding a lock on the database directory, preventing it from being opened.fixEnsure that no other applications or database instances are accessing the same database location. Verify that previous database instances were properly closed. You might need to manually remove the `LOCK` file if a process crashed and left it behind, but do so with caution. -
TypeError: db.put is not a function
cause This usually indicates an attempt to use `db.put()` with a callback function, which was removed in v2.0.0.fixUpdate your code to use the Promise-based API for all database operations. For `db.put`, simply `await db.put(key, value)` without a callback. -
Error: N-API library not found, trying to rebuild from source...
cause The package failed to find a prebuilt binary for your platform and is attempting to compile the native LevelDB module, but the `node-gyp` build tools are missing or misconfigured.fixInstall the necessary `node-gyp` dependencies, including Python, `make`/`build-essential` (Linux), Xcode Command Line Tools (macOS), or Visual C++ Build Tools (Windows). Refer to the `node-gyp` GitHub page for detailed installation instructions for your OS.
Warnings
- breaking Version 3.0.0 introduced a breaking change by upgrading to `abstract-level` v3. This might require updating your code if you are interacting directly with `abstract-level`'s low-level API or specific features that changed.
- breaking Version 2.0.0 removed traditional callback-style APIs for database operations, favoring Promises. Additionally, the `LEVEL_NOT_FOUND` error constant was removed.
- gotcha For platforms without prebuilt binaries (e.g., specific architectures or older OS versions), `classic-level` will attempt to compile from source. This requires a valid `node-gyp` installation, which can be a common source of installation issues.
- gotcha Attempting to open a `ClassicLevel` database at a `location` that is already exclusively locked by another process or another `ClassicLevel` instance will result in a `LEVEL_LOCKED` error.
- gotcha The `UPGRADING.md` file in the repository contains critical information for migrating between major versions. Neglecting to consult it can lead to unexpected behavior or errors.
Install
-
npm install classic-level -
yarn add classic-level -
pnpm add classic-level
Imports
- ClassicLevel
const ClassicLevel = require('classic-level')import { ClassicLevel } from 'classic-level' - ClassicLevel
import ClassicLevel from 'classic-level'
const { ClassicLevel } = require('classic-level') - ClassicLevel
import { ClassicLevel } from 'classic-level/types'import type { ClassicLevel } from 'classic-level'
Quickstart
import { ClassicLevel } from 'classic-level';
import { rmSync } from 'node:fs';
const dbPath = './my-classic-level-db';
async function runExample() {
// Clean up previous run if any
try { rmSync(dbPath, { recursive: true, force: true }); } catch (e) {}
// Create a database instance with JSON value encoding
const db = new ClassicLevel(dbPath, { valueEncoding: 'json' });
try {
// Open the database
await db.open();
console.log('Database opened.');
// Add a single entry
await db.put('user:1', { name: 'Alice', age: 30 });
console.log('Added user:1');
// Add multiple entries using batch operation
await db.batch([
{ type: 'put', key: 'user:2', value: { name: 'Bob', age: 25 } },
{ type: 'put', key: 'user:3', value: { name: 'Charlie', age: 35 } }
]);
console.log('Added user:2 and user:3 via batch');
// Retrieve a value
const user1 = await db.get('user:1');
console.log('Retrieved user:1:', user1);
// Iterate over entries with keys greater than 'user:1'
console.log('Iterating users > user:1:');
for await (const [key, value] of db.iterator({ gt: 'user:1' })) {
console.log(` Key: ${key}, Value:`, value);
}
} catch (error) {
console.error('An error occurred:', error);
} finally {
// Close the database
await db.close();
console.log('Database closed.');
}
}
runExample();