API reference / @jsprismarine/leveldb
@jsprismarine/leveldb
A LevelDB implementation in pure TypeScript, able to read and write the databases that Minecraft: Bedrock Edition stores its worlds in.
Why this exists
Bedrock does not use stock LevelDB. Mojang's fork adds two compression types — Zlib (2) and ZlibRaw (4) — and writes its table blocks with the latter. Every off-the-shelf Node binding builds against upstream LevelDB, which knows only None (0) and Snappy (1) and rejects a Bedrock table outright. The bindings that do handle it are native modules, which would mean a toolchain on every platform the server builds for and no bun build --compile.
So: no native modules, no dependencies at all. node:zlib supplies raw DEFLATE, and the rest — CRC32C, the table and log formats, the manifest, Snappy decompression — is implemented here.
Usage
import { Database, WriteBatch } from '@jsprismarine/leveldb';
const db = await Database.open('/path/to/world/db');
const value = db.get(Buffer.from('~local_player'));
db.write(new WriteBatch().put(key, payload).del(staleKey));
await db.close();Reads are synchronous, backed by a cached file descriptor. open, flush and close are async because they fsync.
Compatibility
Reads compression types 0, 1, 2 and 4; writes 4, which is what the game itself writes. Databases predating the modern chunk formats are rejected rather than guessed at — open such a world in the game once and let it convert.
Never open a database the game has open. Database.open takes the LOCK file to make that loud rather than silently corrupting.
Classes
Interfaces
BatchOperation
Defined in: format/WriteBatch.ts:6
Properties
key
key:
Buffer
Defined in: format/WriteBatch.ts:8
type
type:
ValueType
Defined in: format/WriteBatch.ts:7
value?
optionalvalue?:Buffer<ArrayBufferLike>
Defined in: format/WriteBatch.ts:10
Absent for a deletion.
BlockCacheStats
Defined in: format/BlockCache.ts:5
Current and cumulative point-lookup cache usage.
Properties
dataBytes
dataBytes:
number
Defined in: format/BlockCache.ts:11
Bytes held by evictable data blocks.
hitRate
hitRate:
number
Defined in: format/BlockCache.ts:17
Point lookup hits divided by total cache lookups.
hits
hits:
number
Defined in: format/BlockCache.ts:7
Number of cached blocks returned to a point lookup.
misses
misses:
number
Defined in: format/BlockCache.ts:9
Number of blocks a point lookup had to read and decompress.
pinnedBytes
pinnedBytes:
number
Defined in: format/BlockCache.ts:13
Bytes held by pinned index and filter blocks, which are excluded from the data budget.
residentBytes
residentBytes:
number
Defined in: format/BlockCache.ts:15
Total decompressed bytes resident in the cache.
DatabaseOptions
Defined in: DatabaseOptions.ts:5
Properties
blockCacheSize?
optionalblockCacheSize?:number
Defined in: DatabaseOptions.ts:15
Maximum bytes of decompressed data blocks retained for point lookups.
blockRestartInterval?
optionalblockRestartInterval?:number
Defined in: DatabaseOptions.ts:19
blockSize?
optionalblockSize?:number
Defined in: DatabaseOptions.ts:18
compression?
optionalcompression?:CompressionType
Defined in: DatabaseOptions.ts:21
What blocks are written with. Defaults to what the game itself writes.
compressionLevel?
optionalcompressionLevel?:number
Defined in: DatabaseOptions.ts:22
createIfMissing?
optionalcreateIfMissing?:boolean
Defined in: DatabaseOptions.ts:7
Create the directory and an empty database when there is nothing there. Default true.
errorIfExists?
optionalerrorIfExists?:boolean
Defined in: DatabaseOptions.ts:9
Fail if a database already exists. Default false.
l0CompactionTrigger?
optionall0CompactionTrigger?:number
Defined in: DatabaseOptions.ts:24
How many level 0 files may pile up before they are merged into level 1.
maxFileSize?
optionalmaxFileSize?:number
Defined in: DatabaseOptions.ts:17
The size a compaction's output files are cut at.
readOnly?
optionalreadOnly?:boolean
Defined in: DatabaseOptions.ts:11
Never write, and take no lock, so a world open in the game can still be inspected.
sync?
optionalsync?:boolean
Defined in: DatabaseOptions.ts:26
fsync after every batch. Slow, and unnecessary given the log is replayed on open.
writeBufferSize?
optionalwriteBufferSize?:number
Defined in: DatabaseOptions.ts:13
How much may accumulate in memory before it is flushed to a table.
DatabaseStats
Defined in: Database.ts:54
Properties
blockCache
blockCache:
BlockCacheStats
Defined in: Database.ts:66
Shared point-lookup cache usage and hit rate.
bytesWritten
bytesWritten:
number
Defined in: Database.ts:64
Cumulative WAL, table, manifest, and CURRENT bytes written by this instance.
lastSequence
lastSequence:
bigint
Defined in: Database.ts:62
Highest sequence number ever written to this database.
level0Files
level0Files:
number
Defined in: Database.ts:56
Number of unmerged level 0 files.
memtableBytes
memtableBytes:
number
Defined in: Database.ts:60
Bytes currently held by the mutable and immutable tables.
totalFiles
totalFiles:
number
Defined in: Database.ts:58
Number of live table files at all levels.
KeyRange
Defined in: Database.ts:69
Properties
gte?
optionalgte?:Buffer<ArrayBufferLike>
Defined in: Database.ts:70
lt?
optionallt?:Buffer<ArrayBufferLike>
Defined in: Database.ts:71
Type Aliases
CompressionType
CompressionType = typeof
CompressionType[keyof typeofCompressionType]
Defined in: compression/Compression.ts:13
One of the values of CompressionType.
Variables
CompressionType
constCompressionType:object
Defined in: compression/Compression.ts:13
The compression byte that trails every table block.
Zlib and ZlibRaw are Mojang's additions - upstream LevelDB knows only None and Snappy and returns a corruption error for anything else, which is exactly why a stock binding cannot open a Bedrock world. ZlibRaw is what the game writes: a DEFLATE stream with no zlib header and no trailing Adler-32, since the block already carries a CRC-32C of its own.
Type Declaration
None
readonlyNone:0=0
Snappy
readonlySnappy:1=1
Zlib
readonlyZlib:2=2
ZlibRaw
readonlyZlibRaw:4=4