libsql

A better-sqlite3 compatible driver for libSQL, running local, remote, and embedded-replica databases

Library
npm
v0.5.29
336stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
73/100Good
Development Activity60
Maintenance88
Community64
Maturity52
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
73/100Good
Architecture75
Code Quality72
Innovation68
Learning Curve78

libsql is the official Node.js/Bun/Deno client for libSQL, an open-source fork of SQLite maintained by the Turso team. It deliberately mirrors the better-sqlite3 API (synchronous db.prepare(...).get()/.all()/.run() calls) so existing SQLite codebases can adopt it with minimal rewrites, while adding capabilities SQLite alone doesn’t have: connecting to a remote libSQL server over HTTP, and creating an embedded, in-app replica that syncs from a remote primary for low-latency local reads with eventual write sync.

Under the hood the package is a native Node addon built with NAPI-RS from a Rust core (src/lib.rs), with prebuilt binaries published per-platform (@libsql/darwin-x64, @libsql/linux-arm64-gnu, etc.) and dynamically require()-d based on the running OS/arch, so consumers install a single libsql package and get the right native binary automatically. A libsql/promise entrypoint offers the same API with promises instead of synchronous calls, for environments that need non-blocking I/O.

What You Get

  • A synchronous Database API (compat.js) matching better-sqlite3’s .prepare().get()/.all()/.run() conventions for drop-in adoption
  • A promise-based API via libsql/promise for async workflows without blocking the event loop
  • Remote database connections over HTTP/HTTPS to a libSQL server, with optional auth token support (auth.js)
  • Embedded replica support (db.sync()) that keeps a local file synced from a remote primary for fast local reads
  • Prebuilt native binaries for macOS, Linux (glibc/musl), and Windows across x64/arm64, auto-selected at install/require time

Common Use Cases

  • Migrating an existing better-sqlite3 codebase to libSQL/Turso with minimal API changes
  • Running a local SQLite-compatible database in a serverless or edge function that also needs occasional remote sync
  • Building an offline-first app that writes to a local embedded replica and syncs with a remote libSQL/Turso database when connectivity returns
  • Connecting directly to a hosted Turso database from a Node.js, Bun, or Deno backend using the remote-connection mode

Under The Hood

Architecture - The public JS surface is split across index.js (auto-generated NAPI-RS loader that platform/arch-switches to the correct prebuilt .node binary or optional-dependency package like @libsql/darwin-x64), compat.js (the better-sqlite3-compatible synchronous wrapper, the package’s declared main entry), and promise.js (an async wrapper over the same native bindings). The actual database engine logic lives in a Rust crate (src/lib.rs, src/auth.rs, src/query_timeout.rs) compiled to a native Node addon via napi — Cargo.toml wires up libsql and napi/napi-derive as the core Rust dependencies. Tech Stack - Hybrid Rust/JavaScript: Rust for the native binding and libSQL engine integration, TypeScript declaration files (index.d.ts) for consumer type safety, and @napi-rs/cli driving the cross-compilation to the napi.triples listed in package.json (darwin/linux/win32 across x64/arm64/musl variants). Tests use ava plus a separate integration-tests/ directory exercising the built package end-to-end. Code Quality - The project ships both unit-style Rust/JS tests and a dedicated integration-tests workspace that links the built package and runs real database operations (local, remote, sync, vector) as documented in examples/; the native-binding loader code itself is auto-generated boilerplate (NAPI-RS) and not hand-maintained, keeping the human-authored surface limited to the Rust core and the compat/promise wrappers. API Design - Mirroring better-sqlite3’s method names (prepare, get, all, run, exec) means any developer already familiar with SQLite tooling can be productive immediately; the additional sync() method and syncUrl/authToken constructor options for embedded replicas are the only real departures from the familiar API, which keeps the learning curve low while still surfacing libSQL’s distinguishing remote/replica features.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search