Skip to content

Repository files navigation

LiteDB

An embedded document database for .NET 10, built from scratch with zero runtime dependencies.

Naming note: this project reuses the name LiteDB, which clashes with a well-known open-source database of the same name. It is unrelated and not published to NuGet under the LiteDB id (the package id is a placeholder). Do not publish it as LiteDB without renaming.

What it is

  • SQLite-like deployment: a class library over a single data file (plus a -wal sibling), or a pure in-memory database. Never a server or a separate process.
  • MongoDB-like data model: schemaless BSON documents in named collections, queried with Mongo-style JSON filter strings.
  • ACID storage: a page-based single file with a write-ahead log (WAL), crash recovery, and data that can exceed RAM. The in-memory database runs the identical WAL/commit/checkpoint code path.
  • Secondary indexes: B+tree indexes used automatically by a small query planner.

Quick start

using LiteDB;
using LiteDB.Bson;

using var db = new LiteDatabase(@"C:\data\app.db");   // or LiteDatabase.CreateInMemory()
LiteCollection users = db.GetCollection("users");     // created lazily on first write

BsonValue anaId = users.InsertOne("{ Name: 'Ana', Age: 34, Address: { City: 'Porto' }, Tags: ['admin','dev'] }");
users.InsertMany(new[] { "{ Name: 'Bruno', Age: 28 }", "{ Name: 'Carla', Age: 41 }" });   // atomic batch

users.EnsureIndex("Age");
users.EnsureIndex("Email", unique: true);

IReadOnlyList<BsonDocument> adults =
    users.Find("{ Age: { $gt: 30 } }", new FindOptions { Sort = "{ Age: -1 }", Skip = 0, Limit = 10 });
BsonDocument? ana  = users.FindOne("{ 'Address.City': 'Porto', Tags: 'admin' }");
BsonDocument? doc  = users.FindById(anaId);
long juniors       = users.Count("{ Age: { $lt: 30 } }");
string plan        = users.Explain("{ Age: { $gt: 30 } }");   // "IXSCAN(Age asc, (30, +inf)"

users.ReplaceById(anaId, new BsonDocument { ["Name"] = "Ana", ["Age"] = 35 });
users.UpdateMany("{ Age: { $lt: 30 } }", "{ $set: { Level: 'junior' }, $inc: { Rev: 1 } }");
users.UpdateMany("{ Email: 'x@y.z' }", "{ $set: { Seen: true } }", new UpdateOptions { Upsert = true });

users.DeleteOne("{ Name: 'Bruno' }");
long removed = users.DeleteMany("{ Level: 'junior' }");
users.DropIndex("Age");
db.DropCollection("audit");
IReadOnlyList<string> names = db.ListCollections();
db.Checkpoint();   // manual WAL checkpoint (also on Dispose)

Query language

Filters and updates are relaxed JSON strings (unquoted keys with dots, single quotes, trailing commas) with MongoDB extended-JSON literals ({"$oid":…}, {"$date":…}, {"$numberDecimal":…}, …).

  • Operators: implicit/explicit $eq, $ne, $gt/$gte/$lt/$lte, $in/$nin, $exists, and $and/$or/$not/$nor.
  • Paths: dotted paths, numeric array indexing, and MongoDB array any-element matching ({ Tags: 'admin' } matches an element; { Tags: ['admin','dev'] } matches the whole array).
  • Updates: $set (creates intermediate documents on dotted paths), $inc (numeric type promotion), $unset.

Durability & recovery

Commits append full-page images to the WAL and fsync (with DurabilityMode.Full, the default); DurabilityMode.Lazy skips fsync for tests and bulk load. A checkpoint folds the WAL into the main file and is idempotent, so a crash mid-checkpoint replays cleanly on the next open. The WAL is salt-seeded and CRC-checked, so torn or stale frames are never replayed.

Limits & behavior notes (v1)

  • Document ≤ 16 MiB; index key ≤ 512 B (throws); path depth ≤ 32; page size 8192 (fixed).
  • DateTime has millisecond precision; string comparison is ordinal only.
  • A unique index is non-sparse: documents missing the field all index as null, so at most one may omit it (matching a non-sparse MongoDB unique index).

Not in v1

POCO mapping (use BsonDocument + JSON strings), LINQ, async, encryption, multi-process sharing (FileShare.None, fail fast), aggregation pipeline, $regex/$elemMatch/$size/$type, compound and multi-field-sort indexes, sparse indexes, a public transaction API, and vacuum/Rebuild(). See PLAN.md for the full scope.

Build & test

dotnet build -c Release
dotnet test  -c Release
dotnet run --project samples/LiteDB.Sample

Requires the .NET 10 SDK (pinned in global.json).

About

An embedded document database in .NET, built from scratch with zero runtime dependencies.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages