The Problem It Solves
Every .NET developer building desktop applications, plugins, or portable tools eventually needs an embedded database. The obvious choices are:
SQLite — excellent, but it's native code. The e_sqlite3.dll dependency causes problems in plugin isolation scenarios, complicates cross-platform deployment, and doesn't work in Blazor WebAssembly.
LiteDB — pure .NET, but it's a document database. Entity Framework Core doesn't work naturally with it. If your codebase uses EF Core, switching to LiteDB means rewriting your data layer.
EF Core In-Memory — pure .NET and works with EF Core, but it's not a real database. No persistence, incomplete SQL support, designed only for simple testing scenarios.
WitDatabase fills the gap: a pure-managed, relational database with full EF Core support.
Architecture
Every layer is pluggable. Custom storage backends, encryption providers, and caching strategies can be substituted.
Key Features
Full Entity Framework Core Provider
WitDatabase isn't an adapter or compatibility layer — it's a proper EF Core provider implementing the same interfaces as Npgsql or Microsoft.Data.SqlClient.
// One line change from SQL Server
services.AddDbContext<AppDbContext>(options =>
options.UseWitDb("Data Source=app.witdb"));
Your existing DbContext, entities, migrations, and LINQ queries work unchanged.
Zero Native Dependencies
100% C# code. No P/Invoke, no platform-specific binaries. This enables:
- Plugin isolation — works correctly in separate AssemblyLoadContext
- Blazor WebAssembly — runs in browser with IndexedDB storage
- Simplified deployment — no native DLLs to manage
- True cross-platform — same code on Windows, Linux, macOS, browser
SQL Query Engine
Full SQL support including:
- SELECT, INSERT, UPDATE, DELETE
- JOINs (INNER, LEFT, RIGHT, CROSS)
- Subqueries and CTEs
- Aggregate functions and GROUP BY
- Window functions
- Indexes (B+Tree)
Storage Options
| Engine | Best For |
|---|---|
| B+Tree | Balanced performance for mixed workloads |
| LSM-Tree | Write-heavy scenarios |
| File storage | Persistent .witdb files |
| Memory storage | Fast ephemeral databases for testing |
| IndexedDB | Browser persistence for Blazor WASM |
Security
- AES-GCM encryption — industry-standard authenticated encryption
- ChaCha20-Poly1305 — modern alternative via BouncyCastle
- Encryption at rest with key derivation
ACID Transactions
- Full transaction support with BEGIN/COMMIT/ROLLBACK
- Write-Ahead Logging (WAL) for durability
- MVCC for concurrent read access
Use Cases
Plugin Architectures
When plugins need isolated data storage, native dependencies break down. SQLite's DLLs don't resolve correctly in isolated AssemblyLoadContext. WitDatabase loads and runs like any other .NET assembly.
Integration Testing
Replace slow database containers with instant in-memory or file-based databases:
var options = new DbContextOptionsBuilder<AppDbContext>()
.UseWitDb("Data Source=:memory:")
.Options;
Same DbContext, same migrations, milliseconds instead of minutes.
Portable Applications
Ship a single executable with embedded data. No "please install SQL Server" — just run.
Blazor WebAssembly
Full database capabilities in the browser:
var db = new WitDatabaseBuilder()
.WithIndexedDbStorage("MyApp", jsRuntime)
.WithBTree()
.BuildAsync();
Data persists in browser storage, survives page refresh, works offline.
Desktop Applications
WPF, MAUI, Avalonia — any .NET desktop framework. Single-file deployment, user data in a local .witdb file, optional encryption for sensitive data.
Performance
WitDatabase is optimized for embedded scenarios, not high-throughput servers. For plugin storage, desktop apps, and testing — performance is excellent. For millions of rows with complex analytics — use PostgreSQL.
| Operation | Typical Performance |
|---|---|
| Point query | < 1ms |
| Insert (single) | < 1ms |
| Bulk insert (1000 rows) | < 10ms |
| Complex join query | < 10ms |
Comparison
| Feature | SQLite | LiteDB | WitDatabase |
|---|---|---|---|
| Pure .NET | ❌ | ✅ | ✅ |
| Relational | ✅ | ❌ | ✅ |
| EF Core | ✅ | ⚠️ | ✅ |
| Plugin safe | ❌ | ✅ | ✅ |
| Browser | ⚠️ | ❌ | ✅ |
| Encryption | 💰 | ❌ | ✅ |
Getting Started
dotnet add package OutWit.Database.EntityFramework
public class AppDbContext : DbContext
{
public DbSet<Customer> Customers => Set<Customer>();
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseWitDb("Data Source=app.witdb");
}
That's all. Standard EF Core patterns work as expected.
Links
- Official Website: witdatabase.io
- GitHub Repository: dmitrat/WitDatabase