Skip to content

f0rr0/pglite-oxide

Repository files navigation

pglite-oxide logo

pglite-oxide

Embedded Postgres for Rust tests and local apps.
Real PostgreSQL. Instant testing. Packaged runtime. Direct Rust API or a local Postgres URL.

Usage · Performance · Extensions · Dump & Upgrade · Testing · Tauri

CI crates.io docs.rs MSRV License

pglite-oxide brings PGlite/Postgres to Rust with a small API. Open a database directly with Pglite, or hand PgliteServer to SQLx and any standard Postgres client. The packaged runtime is PostgreSQL 17.5. No local Postgres install, no Docker, no runtime build toolchain.

Add Postgres In One Minute ⚡

Already using SQLx or another Postgres client? Add the crate and point your client at an embedded database URL:

cargo add pglite-oxide
use pglite_oxide::PgliteServer;
use sqlx::{Connection, Row};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let server = PgliteServer::temporary_tcp()?;
    // For a persistent TCP server:
    // let server = PgliteServer::builder().path("./.pglite").start()?;
    let mut conn = sqlx::PgConnection::connect(&server.database_url()).await?;

    let row = sqlx::query("SELECT $1::int4 + 1 AS answer")
        .bind(41_i32)
        .fetch_one(&mut conn)
        .await?;
    assert_eq!(row.try_get::<i32, _>("answer")?, 42);

    conn.close().await?;
    server.shutdown()?;
    Ok(())
}

That's it. Real PostgreSQL, no service setup.

Why pglite-oxide ✨

Postgres should be as easy to add to a Rust project as SQLite.

  • No service tax: no Docker, no local Postgres, no testcontainers.
  • 🔌 Use your real stack: SQLx, tokio-postgres, CLIs, and other clients connect through a normal local URL.
  • 🌉 Proxy included: expose an embedded database to non-Rust tools with pglite-proxy.
  • 🧪 Clean tests: temporary databases are isolated, fast, and removed on drop.
  • 💾 Persistent apps: keep local app data across restarts when you want it.
  • 🧩 Extensions included: pgvector, pg_trgm, hstore, citext, and more.
  • 📦 Portable dumps: use bundled pg_dump for logical backups and upgrade paths.
  • 🚀 Near-native feel: close to native Postgres, fully embedded.

Near-Native Performance 🚀

Current local snapshot on Apple M1 Pro, 16 GB RAM, and macOS 26.4.1. Full numbers and reproduction steps live in the performance guide. Lower is better.

Operation native pg + SQLx pglite-oxide + SQLx vanilla PGlite + SQLx
25,000 INSERTs in one transaction 132.36 ms 149.54 ms 257.02 ms
25,000 INSERTs in one statement 46.14 ms 59.39 ms 117.19 ms
25,000 INSERTs into an indexed table 188.72 ms 253.38 ms 352.64 ms
5,000 indexed SELECTs 81.39 ms 125.31 ms 203.05 ms
25,000 indexed UPDATEs 351.05 ms 578.96 ms 720.63 ms

pglite-oxide stays close to native Postgres while running entirely embedded and consistently performs better than vanilla PGlite.

Extensions 🧩

Bundled extensions are supported, including pgvector, pg_trgm, hstore, citext, ltree, and more. See the extensions guide for the full catalog and usage details.

use pglite_oxide::{extensions, PgliteServer};
use sqlx::Connection;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let server = PgliteServer::builder()
        .path("./.pglite")
        .extension(extensions::VECTOR)
        .start()?;
    let mut conn = sqlx::PgConnection::connect(&server.database_url()).await?;

    sqlx::query("CREATE TABLE IF NOT EXISTS items (embedding vector(3))")
        .execute(&mut conn)
        .await?;
    sqlx::query("INSERT INTO items VALUES ('[1,2,3]')")
        .execute(&mut conn)
        .await?;

    conn.close().await?;
    server.shutdown()?;
    Ok(())
}

Docs

About

Embedded Postgres inside your apps and tests. No Docker, Node.js, or server. As easy as SQLite.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors