Recursive AI

SQLite in C# without native dependencies

All onelite recipes

OneLite reads and writes SQLite database files in managed C# alone, so your app ships no native SQLite binary: one RecursiveAI.OneLite.dll and nothing per platform. It is a preview, 0.2.0-preview.2.

Terminal
dotnet new console -o NoNativeSqlite && cd NoNativeSqlite
dotnet add package RecursiveAI.OneLite --version 0.2.0-preview.2

The package targets net10.0, so you need the .NET 10 SDK. Put this in Program.cs and run dotnet run:

C#
using RecursiveAI.OneLite;
 
await using var db = await Database.OpenAsync("notes.db");   // creates it, in WAL mode
await db.ExecuteScriptAsync(
    "create table if not exists notes (id integer primary key, body text not null)");
 
string body = "Hello from OneLite";
await db.ExecuteAsync($"insert into notes (body) values ({body})"); // {body} is bound
 
foreach (string note in await db.QueryAsync<string>($"select body from notes"))
    Console.WriteLine(note);
Console.WriteLine(await db.ScalarAsync<string>($"select sqlite_version()"));
Console.WriteLine(await db.ScalarAsync<string>($"pragma journal_mode"));
Text
Hello from OneLite
3.53.4
wal

Database.OpenAsync creates notes.db if it is missing and opens it with write-ahead logging (wal), foreign keys on and a 5-second busy timeout. Every {hole} in the $"…" string is a bound parameter, never pasted into the SQL. sqlite_version() reports 3.53.4, the SQLite release OneLite is measured against.

Nothing native in the output

Publish it for Linux x64 and list what ships:

Terminal
dotnet publish -c Release -r linux-x64 --self-contained false -o out
Terminal
find out -type f -printf '%f\n' | sort
Text
NoNativeSqlite
NoNativeSqlite.deps.json
NoNativeSqlite.dll
NoNativeSqlite.pdb
NoNativeSqlite.runtimeconfig.json
RecursiveAI.OneLite.dll

NoNativeSqlite is the app’s own launcher. The same publish of a project using Microsoft.Data.Sqlite 10.0.14 adds libe_sqlite3.so and three SQLitePCLRaw assemblies, and a publish with no runtime identifier carries 23 e_sqlite3 binaries under runtimes/, one per platform. With OneLite there is no native file to pick per platform; in the README’s words, “it runs wherever .NET runs”.

NativeAOT works too. This publishes one self-contained executable, with no trimming or AOT warnings:

Terminal
dotnet publish -c Release -r linux-x64 -p:PublishAot=true -o aot
Terminal
./aot/NoNativeSqlite
Text
Hello from OneLite
Hello from OneLite
3.53.4
wal

The second line is the row this run added: the file keeps the first run’s row.

Check it with sqlite3

The file is an ordinary SQLite database. The sqlite3 shell (3.53.4, from sqlite.org) opens it, sees the same rows, reads the WAL mode from the file and finds nothing wrong:

Terminal
sqlite3 notes.db "select * from notes" "pragma journal_mode" "pragma integrity_check"
Text
1|Hello from OneLite
2|Hello from OneLite
wal
ok

How it differs from Microsoft.Data.Sqlite

  • No native library. Microsoft.Data.Sqlite calls the C library through SQLitePCLRaw and ships e_sqlite3 for each platform. OneLite is the database engine, written in C# on the base class library, so trimming, NativeAOT and browser builds need no native asset.
  • A different API. Microsoft.Data.Sqlite and EF Core can’t run on OneLite yet: in the README’s words, “the Microsoft.Data.Sqlite/EF Core adapter” is “still to come before 1.0”. OneLite has its own ADO.NET provider, RecursiveAI.OneLite.Data (ADO.NET recipe), and the happy-path API used here (create, insert and query).
  • Same files, measured. Files written by OneLite pass sqlite3’s PRAGMA integrity_check and files sqlite3 writes read back identically, in the project’s compatibility measurements against SQLite 3.53.4, which also list every known difference.

Limits

  • A preview: APIs may change between previews.
  • No load_extension: native SQLite extensions don’t load.
  • No speed claim: the project has not published benchmarks yet.

Getting started · All recipes · Compatibility