One connect call. Every database. No C.
Today we’re releasing OxiSQL 0.3.1 — the COOLJAPAN Pure-Rust unified SQL layer: a single SQL surface that spans embedded engines, OLTP wire-protocol clients (PostgreSQL and MySQL), and a SQLite-compatible embedded path, all behind one async facade.
No libpq. No libmysqlclient. No libsqlite3. No FFI. No -sys crates. Pure Rust from the connection string down to the bytes on the wire — and on macOS, even objc2-free.
The problem
Every service that talks to a database in Rust today tends to make the same compromise. Reach for rusqlite and you link C SQLite. Reach for tokio-postgres against native-tls/ring, or sqlx with a *-sys TLS provider, and you drag libssl-dev, libpq-dev, or libsqlite3-dev onto the CI critical path. Each backend wants a different crate, a different connection type, a different parameter-binding convention — and a different native library that has to be present at build time and again at deploy time.
That is exactly the kind of native dependency NoFFI — the COOLJAPAN initiative to replace every C/C++/Fortran/-sys FFI dependency in the Rust ecosystem with a clean, memory-safe, 100% Pure Rust implementation — exists to eliminate. OxiSQL collapses those compromises into one facade. It defaults to Pure-Rust drivers (tokio-postgres, mysql_async, GlueSQL, and the C-free oxisqlite engine), and routes all TLS through OxiTLS with the rustcrypto provider — no ring, no openssl-sys, no native-tls. Under the COOLJAPAN Pure Rust Policy, oxisql-sqlite-compat is the sanctioned replacement for rusqlite.
The default feature set is not merely C-avoiding — it is provably C-free:
CC=/usr/bin/false cargo build --workspace # → exit 0
cargo build --workspace # → 0 warnings
What we built
OxiSQL ships as 20 workspace crates: a 10-crate facade/driver layer, a 7-crate C-free oxisqlite-* engine, a perf benchmark crate, and two vendored crates applied via [patch.crates-io] — rustls-rustcrypto-patched (fixes a CRL-parsing advisory) and whoami-patched (drops objc2-system-configuration from the macOS path).
1. The facade — oxisql. A single oxisql::connect(uri) call dispatches by URI scheme to in-memory/persistent embedded engines, PostgreSQL, MySQL, the C-free SQLite engine, or Apache DataFusion. Its companions are connect_pooled, connect_pool, connect_with_tls, and connect_datafusion.
2. The async core — oxisql-core. Trait-based and backend-agnostic: Connection, Transaction, ConnectionPool, Row, PreparedStatement, SchemaInspector, and a 13-variant Value type that covers the full type surface of every supported backend (plus a zero-allocation BorrowedValue<'a> view for high-throughput row iteration). Named parameters — :name, $name, and @name — are default methods on the Connection trait, so every backend inherits execute_named / query_named with no per-backend implementation.
3. The backends.
- Embedded (
memory://) wraps GlueSQL for in-memory SQL, with persistent variants on redb (redb://), fjall (fjall://), and sled (sled://), plusexport_as_sql()/import_from_sql(). - PostgreSQL (
postgres://) ridestokio-postgres— nolibpq— with prepared statements, transactions, COPY bulk ingestion, LISTEN/NOTIFY, pipeline batching, and extended type mapping (DATE, TIMESTAMP, UUID, JSONB, NUMERIC, ARRAY). - MySQL (
mysql://) ridesmysql_async— nolibmysqlclient— with prepared statements, transactions, multi-result-sets for stored procedures, LOAD DATA bulk ingestion, the binary protocol, and extended type mapping (DECIMAL, DATETIME(6), JSON, ENUM). - SQLite-compat (
sqlite://) —oxisql-sqlite-compat— runs on the in-tree, C-freeoxisqliteengine with full transactionalROLLBACK, UPSERT, and transparent schema re-prepare. - DataFusion (
datafusion://) bridges any backend’s tables into Apache DataFusion for cross-backend OLAP with filter/projection/limit pushdown viaconnect_datafusion.
4. The C-free SQLite engine — oxisqlite-*. The SQLite-compatible path is served by an in-tree fork of the limbo engine (limbo 0.0.22, MIT) from which every C touchpoint has been excised: the mimalloc C allocator, the lemon.c parser generator (the parser is pre-generated and committed), and the built/git2 C-backed build-info collection. The result is a genuinely C-free SQLite backend — no libsqlite3, no mimalloc, no lemon. Its seven crates (oxisqlite, oxisqlite-core, oxisqlite-ext, oxisqlite-macros, oxisqlite-sqlite3-parser, oxisqlite-time, oxisqlite-uuid) are internal — consumed by oxisql-sqlite-compat, not part of OxiSQL’s public surface. The core engine carries a B-tree, pager, WAL, VDBE, transactions, ANALYZE, a System-R optimizer with real statistics, and WITHOUT ROWID tables.
Getting Started
Add OxiSQL with the backends you need:
[dependencies]
oxisql = { version = "0.3.1", features = ["embedded", "postgres", "pool-embedded", "migrate"] }
A minimal in-memory example over the embedded GlueSQL backend:
#[tokio::main]
async fn main() -> Result<(), oxisql::OxiSqlError> {
let conn = oxisql::connect("memory://").await?;
conn.execute("CREATE TABLE users (id INTEGER, name TEXT)", &[]).await?;
conn.execute("INSERT INTO users VALUES (1, 'Alice')", &[]).await?;
let rows = conn.query("SELECT id, name FROM users", &[]).await?;
for row in &rows {
println!("{:?}", row);
}
Ok(())
}
The same trait surface reaches every other backend — just change the URI. To use the C-free SQLite path with real transactional ROLLBACK:
use oxisql::SqliteConnection;
use oxisql::prelude::*;
#[tokio::main]
async fn main() -> Result<(), oxisql::OxiSqlError> {
let conn = SqliteConnection::open_memory().await?;
conn.execute("CREATE TABLE t (id INTEGER, name TEXT)", &[]).await?;
// BEGIN ... ROLLBACK discards the INSERT.
conn.execute("BEGIN", &[]).await?;
conn.execute("INSERT INTO t VALUES (1, 'Alice')", &[]).await?;
conn.execute("ROLLBACK", &[]).await?;
let rows = conn.query("SELECT COUNT(*) FROM t", &[]).await?;
println!("rows after ROLLBACK: {:?}", rows); // → one row holding COUNT(*) = 0
Ok(())
}
You can reach the same backend through the facade with oxisql::connect("sqlite::memory:") or oxisql::connect("sqlite://path/to/file.db").
Highlights
- One facade, many backends. A single
connect(uri)dispatches by URI scheme to embedded, PostgreSQL, MySQL, C-free SQLite, or DataFusion. - Pure Rust by default. The default feature set is 100% C-free, and proven absent with
CC=/usr/bin/false. - Async, trait-based core.
Connection,Transaction,ConnectionPool,Row, and a 13-variantValueunify every backend behind one ergonomic async API. - Named parameters everywhere.
:name,$name, and@namework on all backends as defaultConnectionmethods. - Composable middleware.
LoggingConnection,MetricsConnection, andRetryConnectionwrap anyBox<dyn Connection>;MultiConnectionfans a single handle across several backends. - TLS without C. OxiTLS + rustls-rustcrypto for PostgreSQL and MySQL — no
ring, noopenssl-sys, nonative-tls. - Pooling and migrations. deadpool-backed pools for every backend, and a file-based, 14-digit-timestamped migration runner.
- Optional REPL. An
oxisql-replbinary (thereplfeature) with.help,.tables,.schema <t>, and.quit.
Tips
- Pick backends with feature flags.
embedded,postgres,mysql,sqlite,datafusioneach enable a URI scheme;redb/fjall/sledadd persistent embedded engines and implyembedded. - Pool any backend. Pair a backend with its pool feature —
pool-postgres,pool-mysql,pool-embedded,pool-sqlite-compat— and reach forconnect_pooled(uri, size)to get aBox<dyn ConnectionPool>that works with any backend URI. - Use named parameters for portable SQL.
execute_named/query_named(viause oxisql::prelude::*) rewrite:name/$name/@nameto positional form before dispatch, so the same query runs unchanged across every backend; values implementToSqlValue. - Run TLS through OxiTLS. PostgreSQL and MySQL route TLS through OxiTLS + rustcrypto — no
ring, noopenssl-sys— viaconnect_with_tls; the workspace additionally patches the rustls-rustcrypto provider against RUSTSEC-2026-0104. - Keep the C compiler disabled. The default workspace build is C-free; verify it locally with
CC=/usr/bin/false cargo build --workspace. The native epoll/kqueue event loop andload-extensionpaths inoxisqlite-coreare opt-in features (native-io,load-extension), so default builds stay 100% Pure Rust. - Reach for DataFusion when you need OLAP. Use
connect_datafusion("datafusion://")to obtain anOxiSqlContext, then register tables from any backend for cross-backend analytical queries.
Part of the COOLJAPAN ecosystem
OxiSQL is the database tier of the NoFFI family — eliminating libpq, libmysqlclient, libsqlite3/rusqlite, and libssl/native-tls/ring in one facade. It depends on OxiTLS (transport / TLS), oxicode (row serde), OxiCrypto (encryption-at-rest), and OxiStore (lower storage layer); and it is depended on by oxirouter, oxirs, oxify, oxigdal-db-connectors, oximedia, oxigaf, and oxirag. Default features are 100% Pure Rust: a single static binary, no system libraries, no build-time C toolchain.
Repository: https://github.com/cool-japan/oxisql
Star the repo if you want a future where talking to a database from Rust means one connect call, no native driver, and no C on the build path. 🦀
Pure Rust SQL — sovereign, safe, and FFI-free.
— KitaSan at COOLJAPAN OÜ June 24, 2026