SqliteWasmBlazor 0.8.5-pre
dotnet add package SqliteWasmBlazor --version 0.8.5-pre
NuGet\Install-Package SqliteWasmBlazor -Version 0.8.5-pre
<PackageReference Include="SqliteWasmBlazor" Version="0.8.5-pre" />
<PackageVersion Include="SqliteWasmBlazor" Version="0.8.5-pre" />
<PackageReference Include="SqliteWasmBlazor" />
paket add SqliteWasmBlazor --version 0.8.5-pre
#r "nuget: SqliteWasmBlazor, 0.8.5-pre"
#:package SqliteWasmBlazor@0.8.5-pre
#addin nuget:?package=SqliteWasmBlazor&version=0.8.5-pre&prerelease
#tool nuget:?package=SqliteWasmBlazor&version=0.8.5-pre&prerelease
SqliteWasmBlazor
The first known solution providing true filesystem-backed SQLite database with full EF Core support for Blazor WebAssembly.
Try the Live Demo - Experience persistent SQLite database in your browser! Can be installed as a Progressive Web App (PWA) for offline use.
Related Projects
SqliteWasmBlazor is part of a family of libraries for building offline-first Blazor applications:
| Project | Description |
|---|---|
| RxBlazorV2 | Reactive programming framework for Blazor built on R3. Uses Roslyn source generators for observable models with reactive property bindings, command patterns, and automatic component generation. |
| BlazorPRF | PRF-based deterministic encryption for Blazor WebAssembly using the WebAuthn PRF extension. Enables client-side encryption with biometric authentication — keys derived from passkeys for passwordless encrypt/decrypt workflows. |
Together these enable a complete offline-first stack: persistent local storage (SqliteWasmBlazor) + reactive state management (RxBlazorV2) + client-side encryption with biometric auth (BlazorPRF).
Coming soon: BlazPulse — a universal offline-first delta sync framework tying all of these together. Bidirectional sync between distributed SQLite databases with hash-protected incremental deltas and Ed25519 cryptographic authentication.
About This Project
This is a non-commercial hobby project maintained in my spare time - no fixed update cycle or roadmap. However, "hobby" refers to time and commitment, not craftsmanship: the project is developed with professional standards including proper test coverage and attention to code quality.
Open source thrives on community involvement. The project grows through bug reports, feature requests, pull requests, and real-world feedback. If you're considering this for production use, I'd encourage you to contribute back - that's how open source stays alive, not through promises from a single maintainer, but through shared ownership.
Stability & Status
The public API surface is intentionally kept minimal to reduce the risk of breaking changes. While the API has been stable in practice, this project is pre-1.0: broader real-world feedback is needed before committing to long-term API guarantees. Contributions and usage reports help move toward that goal.
What's New
- V2 Worker-Side Bulk Import/Export - Worker-side prepared statement loops for 10-50x faster import. Self-describing V2 MessagePack format with column metadata. Memory-safe streaming for large datasets (details)
- Multi-Part Export - Large databases automatically split into manageable parts with a meta file. Adaptive part sizing based on configurable MB limit
- Seed Server - PHP REST API + Blazor UI for uploading/downloading seed files to/from a server. One-click database provisioning for new clients (details)
- Raw Database Import/Export - Export and import complete .db files directly from/to OPFS with schema validation and automatic backup/restore on failure (details)
- Multi-Database Support - Run multiple independent SQLite databases simultaneously in the same Web Worker (details)
- Incremental Database Export/Import - File-based delta sync with checkpoint management and conflict resolution (details)
- Real-World Sample - Check out the Datasync TodoApp for offline-first data synchronization with SqliteWasmBlazor
Breaking Changes
- v0.7.2-pre -
SqliteWasmWorkerBridgeis now internal. UseISqliteWasmDatabaseServicevia DI instead:// Program.cs - add service registration builder.Services.AddSqliteWasm(); // Components - inject the interface @inject ISqliteWasmDatabaseService DatabaseService // Replace SqliteWasmWorkerBridge.Instance.DeleteDatabaseAsync(...) // with: DatabaseService.DeleteDatabaseAsync(...)
What Makes This Special?
Unlike other Blazor WASM database solutions that use in-memory storage or IndexedDB emulation, SqliteWasmBlazor is the first implementation that combines:
- True Filesystem Storage - Uses OPFS (Origin Private File System) with synchronous access handles
- Full EF Core Support - Complete ADO.NET provider with migrations, relationships, and LINQ
- Real SQLite Engine - Official sqlite-wasm (3.50.4) running in Web Worker
- Persistent Data - Survives page refreshes, browser restarts, and even browser updates
- No Server Required - Everything runs client-side in the browser
| Solution | Storage | Persistence | EF Core | Limitations |
|---|---|---|---|---|
| InMemory | RAM | None | Full | Lost on refresh |
| IndexedDB | IndexedDB | Yes | Limited | No SQL, complex API |
| SQL.js | IndexedDB | Yes | None | Manual serialization |
| besql | Cache API | Yes | Partial | Emulated filesystem |
| SqliteWasmBlazor | OPFS | Yes | Full | None! |
Public API
SqliteWasmBlazor exposes a stable public API for database management operations via dependency injection:
ISqliteWasmDatabaseService
The primary interface for database operations outside of EF Core:
public interface ISqliteWasmDatabaseService
{
// Database management
Task<bool> ExistsDatabaseAsync(string databaseName, CancellationToken ct = default);
Task DeleteDatabaseAsync(string databaseName, CancellationToken ct = default);
Task RenameDatabaseAsync(string oldName, string newName, CancellationToken ct = default);
Task CloseDatabaseAsync(string databaseName, CancellationToken ct = default);
// Raw .db file import/export
Task ImportDatabaseAsync(string databaseName, byte[] data, CancellationToken ct = default);
Task<byte[]> ExportDatabaseAsync(string databaseName, CancellationToken ct = default);
// V2 bulk import/export (worker-side prepared statement loops)
Task<int> BulkImportAsync(string databaseName, byte[] payload,
ConflictResolutionStrategy conflictStrategy = ConflictResolutionStrategy.None,
CancellationToken ct = default);
Task<byte[]> BulkExportAsync(string databaseName, BulkExportMetadata metadata,
CancellationToken ct = default);
}
Usage in components:
@inject ISqliteWasmDatabaseService DatabaseService
@code {
private async Task ResetDatabaseAsync()
{
// Delete and recreate database
await DatabaseService.DeleteDatabaseAsync("MyApp.db");
await using var context = await DbContextFactory.CreateDbContextAsync();
await context.Database.MigrateAsync();
}
private async Task ExportAsync()
{
// Export raw .db file (closes DB for consistent snapshot, auto-reopens on next query)
byte[] data = await DatabaseService.ExportDatabaseAsync("MyApp.db");
}
private async Task ImportAsync(byte[] data)
{
// Import raw .db file (validates SQLite header)
await DatabaseService.ImportDatabaseAsync("MyApp.db", data);
}
}
Other Public Types
| Type | Purpose |
|---|---|
SqliteWasmConnection |
ADO.NET DbConnection for direct SQL access |
SqliteWasmCommand |
ADO.NET DbCommand for query execution |
SqliteWasmDataReader |
ADO.NET DbDataReader for result iteration |
SqliteWasmParameter |
ADO.NET DbParameter for query parameters |
SqliteWasmTransaction |
ADO.NET DbTransaction for transaction support |
IDBInitializationService |
Tracks database initialization state and errors |
All internal implementation details (worker bridge, serialization, etc.) are encapsulated and not part of the public API.
Installation
NuGet Package
dotnet add package SqliteWasmBlazor --prerelease
Or install a specific version:
dotnet add package SqliteWasmBlazor --version 0.6.5-pre
Visit NuGet.org for the latest version.
From Source
git clone https://github.com/bernisoft/SqliteWasmBlazor.git
cd SqliteWasmBlazor
dotnet build
Quick Start
1. Configure Your Project
Program.cs:
using SqliteWasmBlazor;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
// Add your DbContext with SqliteWasm provider
builder.Services.AddDbContextFactory<TodoDbContext>(options =>
{
var connection = new SqliteWasmConnection("Data Source=TodoDb.db");
options.UseSqliteWasm(connection);
});
// Register initialization service
builder.Services.AddSingleton<IDBInitializationService, DBInitializationService>();
// Register SqliteWasm database management service (for ISqliteWasmDatabaseService)
builder.Services.AddSqliteWasm();
var host = builder.Build();
// Initialize SqliteWasm database with automatic migration support
await host.Services.InitializeSqliteWasmDatabaseAsync<TodoDbContext>();
await host.RunAsync();
The InitializeSqliteWasmDatabaseAsync extension method automatically:
- Initializes the Web Worker bridge
- Applies pending migrations (with automatic migration history recovery)
- Handles multi-tab conflicts with helpful error messages
- Tracks initialization status via
IDBInitializationService
2. Define Your DbContext
using Microsoft.EntityFrameworkCore;
public class TodoDbContext : DbContext
{
public TodoDbContext(DbContextOptions<TodoDbContext> options) : base(options) { }
public DbSet<TodoItem> TodoItems { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<TodoItem>(entity =>
{
entity.HasKey(e => e.Id);
entity.Property(e => e.Title).IsRequired().HasMaxLength(200);
});
}
}
public class TodoItem
{
public int Id { get; set; }
public string Title { get; set; }
public bool IsCompleted { get; set; }
public DateTime CreatedAt { get; set; }
}
3. Use in Your Components
@inject IDbContextFactory<TodoDbContext> DbFactory
<h3>Todo List</h3>
@foreach (var todo in todos)
{
<div>
<input type="checkbox" @bind="todo.IsCompleted" @bind:after="() => SaveTodo(todo)" />
<span>@todo.Title</span>
</div>
}
@code {
private List<TodoItem> todos = new();
protected override async Task OnInitializedAsync()
{
await using var db = await DbFactory.CreateDbContextAsync();
todos = await db.TodoItems.OrderBy(t => t.CreatedAt).ToListAsync();
}
private async Task SaveTodo(TodoItem todo)
{
await using var db = await DbFactory.CreateDbContextAsync();
db.TodoItems.Update(todo);
await db.SaveChangesAsync(); // Automatically persists to OPFS!
}
}
Features
Full EF Core Support
// Migrations
await dbContext.Database.MigrateAsync();
// Complex queries with LINQ
var results = await dbContext.Orders
.Include(o => o.Customer)
.Where(o => o.Total > 100)
.OrderByDescending(o => o.Date)
.ToListAsync();
// Relationships
public class Order
{
public int Id { get; set; }
public Customer Customer { get; set; }
public List<OrderItem> Items { get; set; }
}
// Decimal arithmetic (via ef_ scalar functions)
var expensive = await dbContext.Products
.Where(p => p.Price * 1.2m > 100m)
.ToListAsync();
High Performance
- Efficient Serialization - JSON for requests (small), MessagePack for responses (optimized for data)
- Typed Column Information - Worker sends type metadata to reduce .NET marshalling overhead
- OPFS SAHPool - Near-native filesystem performance with synchronous access
- Direct Execution - Queries run directly on persistent storage, no copying needed
Enterprise-Ready
- Type Safety - Full .NET type system with proper decimal support
- EF Core Functions - All
ef_*scalar and aggregate functions implemented - JSON Collections - Store
List<T>with proper value comparers - Logging - Configurable logging levels (Debug/Info/Warning/Error)
- Error Handling - Proper async error propagation
Documentation
| Topic | Description |
|---|---|
| Architecture | Worker-based architecture, how it works, technical details |
| ADO.NET Usage | Using SqliteWasmBlazor without EF Core, transactions |
| Advanced Features | Migrations, FTS5 search, JSON collections, logging |
| Multi-Database | Running multiple databases, cross-database references |
| Bulk Import/Export | V2 format, multi-part export, delta sync, type conversions |
| Seed Server | PHP API setup, cloud seeding, Herd/Apache configuration |
| Recommended Patterns | Multi-view pattern, data initialization best practices |
| FAQ | Common questions and browser support |
| Changelog | Release notes and version history |
Seed Server
The Seed Server enables cloud-based database provisioning — upload seed data from one client and download it on another. Useful for initial client-side database setup without building the data locally.
Setup
The SeedApi/ folder contains a PHP REST API:
# Local development with Herd/Valet
cd SeedApi
herd link seed-api
herd secure seed-api
# Production (Apache) — just copy these files:
# seed-api.php, index.php, .htaccess
Configure the client in wwwroot/appsettings.json:
{
"seedApiUrl": "seed-api.test",
"exportPartSizeMb": 250,
"cloudPartSizeMb": 40
}
The seedApiUrl is the server domain (without protocol). It can be temporarily overridden on the Seed Server page — useful for testing with the deployed GitHub Pages demo.
API Endpoints
| Method | URL | Description |
|---|---|---|
| GET | /api/seeds |
List all seeds |
| GET | /api/seeds/{name} |
Seed metadata |
| GET | /api/seeds/{name}/{file} |
Download file |
| POST | /api/seeds/{name} |
Upload file (multipart form) |
| DELETE | /api/seeds/{name} |
Delete seed + all parts |
Configuration
exportPartSizeMb— max part size in MB for local file export (default: 250)cloudPartSizeMb— max part size in MB for cloud upload (auto-synced from.htaccessat build time, default: 40)- PHP upload limits in
SeedApi/.htaccesscontrol the server-side maximum
See Seed Server docs for detailed setup instructions.
Browser Support
| Browser | Version | OPFS Support |
|---|---|---|
| Chrome | 108+ | Full SAH support |
| Edge | 108+ | Full SAH support |
| Firefox | 111+ | Full SAH support |
| Safari | 16.4+ | Full SAH support |
All modern browsers (2023+) support OPFS with Synchronous Access Handles, including mobile browsers (iOS/iPadOS Safari, Android Chrome).
Roadmap
- Core ADO.NET provider
- OPFS SAHPool integration
- EF Core migrations support
- MessagePack serialization
- Custom EF functions (decimals)
- FTS5 full-text search with highlighting and snippets
- MudBlazor demo app
- NuGet package pre-release
- Database export/import API (MessagePack serialization + raw .db files)
- Backup/restore utilities (delta sync with checkpoints)
- Raw database import/export with schema validation
- Multi-database support
- V2 worker-side bulk import/export with prepared statement loops
- Multi-part export for large databases
- Seed Server API for cloud-based database provisioning
- Stable NuGet package release
- Server-side delta generation from SQLite databases
Contributing
Contributions welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Submit a pull request
Credits
Author: bernisoft License: MIT
Built with:
- SQLite - The world's most deployed database
- sqlite-wasm - Official SQLite WebAssembly build
- Entity Framework Core - Modern data access
- MessagePack - Efficient binary serialization
- MudBlazor - Material Design components
License
MIT License - Copyright (c) 2025 bernisoft
See LICENSE file for details.
Built with love for the Blazor community
If you find this useful, please star the repository!
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- MessagePack (>= 3.1.4)
- Microsoft.EntityFrameworkCore.Relational (>= 10.0.5)
- Microsoft.EntityFrameworkCore.Sqlite (>= 10.0.5)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on SqliteWasmBlazor:
| Package | Downloads |
|---|---|
|
BlazorPRF.Persistence
Ready-to-use persistence layer for BlazorPRF applications. Provides trusted contacts, invitations, and settings storage using EF Core with SQLite. |
|
|
BBH.SqliteWasmBlazor
A Blazor WebAssembly library for SQLite integration in browser history applications |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated | |
|---|---|---|---|
| 0.8.5-pre | 131 | 4/2/2026 | |
| 0.8.4-pre | 67 | 4/1/2026 | |
| 0.8.3-pre | 70 | 3/31/2026 | |
| 0.8.1-pre | 135 | 3/27/2026 | |
| 0.8.0-pre | 62 | 3/18/2026 | |
| 0.7.2-pre | 160 | 1/28/2026 | |
| 0.7.1-pre | 67 | 1/27/2026 | |
| 0.7.0-pre | 1,288 | 11/17/2025 | |
| 0.6.9-pre | 221 | 11/16/2025 | |
| 0.6.8-pre | 125 | 11/15/2025 | |
| 0.6.7-pre | 225 | 11/14/2025 | |
| 0.6.6-pre | 216 | 11/14/2025 | |
| 0.6.5-pre | 271 | 11/13/2025 | |
| 0.6.4-pre | 268 | 11/13/2025 | |
| 0.6.3-pre | 267 | 11/13/2025 | |
| 0.6.2-pre | 568 | 11/13/2025 | |
| 0.6.0-pre | 277 | 11/12/2025 |
- Full EF Core ADO.NET provider
- OPFS SAHPool persistence
- MessagePack binary protocol
- Complete migration support
- Custom EF Core decimal functions
- Dual SQLite instance architecture