{"id":17180,"library":"browser-level","title":"browser-level","description":"`browser-level` is a JavaScript library providing an `abstract-level` compliant database interface designed specifically for web browsers, utilizing IndexedDB as its backend. The current stable version is 3.0.0. It serves as the spiritual successor to `level-js`, offering a modern, `abstract-level`-compatible API for client-side data persistence. Releases typically align with major upgrades to its underlying `abstract-level` dependency, ensuring compatibility with the broader Level ecosystem. A key differentiator is its seamless integration with browser environments, providing first-class support for both Uint8Array and Buffer (via an optional shim) for keys and values. However, due to IndexedDB's inherent limitations, `browser-level` iterators do not offer strict snapshot guarantees across multiple `next()` or `nextv()` calls, which means concurrent writes might be visible to an ongoing iteration. This necessitates careful handling for applications requiring strict transactional isolation during iteration.","status":"active","version":"3.0.0","language":"javascript","source_language":"en","source_url":"https://github.com/Level/browser-level","tags":["javascript","level","leveldb","indexeddb","abstract-level","typescript"],"install":[{"cmd":"npm install browser-level","lang":"bash","label":"npm"},{"cmd":"yarn add browser-level","lang":"bash","label":"yarn"},{"cmd":"pnpm add browser-level","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core API contract and dependency.","package":"abstract-level","optional":false},{"reason":"Used for Buffer support in browser environments; can be omitted if not needed.","package":"buffer","optional":true}],"imports":[{"note":"Preferred import style for TypeScript and modern ES module contexts. CommonJS `require` is also supported but not recommended for new TypeScript projects.","wrong":"const { BrowserLevel } = require('browser-level')","symbol":"BrowserLevel","correct":"import { BrowserLevel } from 'browser-level'"},{"note":"While `BrowserLevel` extends `AbstractLevel`, directly importing types from `abstract-level` is common for type declarations when interacting with the generic Level API.","symbol":"AbstractLevel","correct":"import type { AbstractLevel } from 'abstract-level'"},{"note":"`browser-level` is the successor to `level-js` and is `abstract-level` compliant. Do not attempt to use `level-js` specific APIs or compatibility layers if migrating.","wrong":"import leveljs from 'level-js'","symbol":"LevelUp compatibility","correct":"import { BrowserLevel } from 'browser-level'"}],"quickstart":{"code":"import { BrowserLevel } from 'browser-level';\nimport type { BatchOperation } from 'abstract-level';\n\nasync function runDbExample() {\n  // Create a database called 'example' with JSON encoding\n  const db = new BrowserLevel('example', { valueEncoding: 'json' });\n\n  // Ensure the database is opened before operations\n  await db.open();\n\n  try {\n    // Add an entry with key 'a' and value 1\n    await db.put('a', 1);\n    console.log('Put key 'a':', await db.get('a'));\n\n    // Add multiple entries using batch\n    const batchOperations: BatchOperation<string, number>[] = [\n      { type: 'put', key: 'b', value: 2 },\n      { type: 'put', key: 'c', value: 3 }\n    ];\n    await db.batch(batchOperations);\n    console.log('Batch operations completed.');\n\n    // Get value of key 'b'\n    const valueB = await db.get('b');\n    console.log('Value of key 'b':', valueB); // Expected: 2\n\n    // Iterate entries with keys that are greater than 'a'\n    console.log('Iterating entries > 'a':');\n    for await (const [key, value] of db.iterator({ gt: 'a' })) {\n      console.log(`  Key: ${key}, Value: ${value}`);\n    } // Expected: b, 2 and c, 3\n\n  } catch (error) {\n    console.error('Database operation failed:', error);\n  } finally {\n    // Always close the database when done\n    await db.close();\n    console.log('Database closed.');\n  }\n}\n\nrunDbExample();","lang":"typescript","description":"This quickstart demonstrates how to create a `BrowserLevel` database, perform basic `put`, `batch`, `get`, and `iterator` operations, and properly open and close the database in a browser environment using TypeScript."},"warnings":[{"fix":"Consult the `UPGRADING.md` guides for both `browser-level` and `abstract-level` to understand necessary API adjustments and potential behavior changes.","message":"Version 3.0.0 introduces a breaking change by upgrading to `abstract-level` version 3. This may require updating your code to align with `abstract-level` v3's API changes.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Refer to the `UPGRADING.md` documents for `browser-level` v2 and `abstract-level` v2 to adapt your application code.","message":"Version 2.0.0 introduced breaking changes by upgrading to `abstract-level` version 2. This impacted API compatibility with previous versions of `abstract-level`.","severity":"breaking","affected_versions":">=2.0.0 <3.0.0"},{"fix":"If strict snapshotting is critical, use `iterator.all()` immediately after creation to fetch all relevant entries within a single, atomic operation.","message":"`browser-level` iterators do not provide strict snapshot guarantees across successive calls to `iterator.next()` or `iterator.nextv()` due to IndexedDB limitations. Concurrent writes might be visible during an ongoing iteration.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always use the asynchronous `db.get(key)` method and `await` its result.","message":"The synchronous `db.getSync()` method is not supported in `browser-level`, unlike some other `abstract-level` implementations.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Remove `createIfMissing` and `errorIfExists` from your `BrowserLevel` constructor options. IndexedDB inherently handles database creation and existence.","message":"The constructor options `createIfMissing` and `errorIfExists` are not supported by `browser-level`.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Replace `db.getSync(key)` with `await db.get(key)` for asynchronous retrieval.","cause":"Attempting to use the synchronous `getSync` method which is not implemented in `browser-level`.","error":"TypeError: db.getSync is not a function"},{"fix":"Remove these options from the `BrowserLevel` constructor. IndexedDB manages database creation internally without these specific flags.","cause":"Passing the `createIfMissing` or `errorIfExists` options to the `BrowserLevel` constructor.","error":"Error: The `createIfMissing` option is not supported by this database."},{"fix":"Ensure that `db.open()` is called and awaited before any database operations, and that `db.close()` is called only when all operations are complete. Avoid performing operations during database shutdown.","cause":"Attempting database operations after `db.close()` has been called or while the database is in a closing state.","error":"DOMException: Failed to execute 'transaction' on 'IDBDatabase': The database connection is closing."}],"ecosystem":"npm","meta_description":null}