@tursodatabase/database | @tursodatabase/sync | @tursodatabase/serverless | @libsql/client | |
|---|---|---|---|---|
| Use case | Local / embedded database | Local database + cloud sync | Remote access (servers, containers, serverless, edge) | ORM support (Drizzle, Prisma) |
| Engine | Turso Database (rewrite) | Turso Database (rewrite) | Turso Database | libSQL (SQLite fork) |
| Dependencies | Native (Node.js, WASM) | Native (Node.js) | fetch only — zero native deps | Requires Node.js or /web subpath |
| Concurrent writes | Yes (MVCC) | Yes (MVCC) | Planned | Not supported |
| Sync | — | push/pull (local-first) | — | Embedded Replicas (writes go to cloud primary) |
| ORM support | Drizzle (beta) | — | — | Drizzle, Prisma, and others |
@tursodatabase/database for local/embedded use, @tursodatabase/sync for local + cloud sync, or @tursodatabase/serverless for any application that connects to a remote Turso Cloud database (Node.js servers, Docker containers, serverless functions, edge runtimes). Using an ORM? Use @libsql/client — it’s production-ready and supported by Drizzle, Prisma, and others. Drizzle has beta support for @tursodatabase/database for local/embedded use.
The following runtime environments are known to be compatible:
- Node.js version 12 or later
- Deno
- CloudFlare Workers
- Netlify & Vercel Edge Functions
@tursodatabase/database
For local and embedded use. Built on the Turso Database engine with concurrent writes (MVCC) and async I/O.Installing
Initializing
Querying
Encryption
Encrypt local databases at rest using theencryption option:
aegis256, aegis256x2, aegis128l, aegis128x2, aegis128x4, aes256gcm, aes128gcm.
Encrypted databases cannot be read as standard SQLite databases — you must use the Turso Database engine to open them.
Turso Cloud databases can also be encrypted with bring-your-own-key — learn more.
@tursodatabase/sync
For local database with cloud sync. All reads and writes happen locally; usepush() to send changes to the cloud and pull() to fetch remote changes.
Installing
Initializing
Push and Pull
Checkpoint
Compact the local WAL to bound disk usage while preserving sync state:Stats
@tursodatabase/serverless
The recommended package for any application that connects to a remote Turso Cloud database — Node.js servers, Docker containers, serverless functions (AWS Lambda, Vercel Functions), and edge runtimes (Cloudflare Workers, Deno Deploy). Uses onlyfetch — zero native dependencies, works everywhere fetch is available.
Installing
Initializing
@libsql/client API, use the compat module:
Querying
@libsql/client
The@libsql/client package is built on libSQL, the open-source fork of SQLite that powers Turso Cloud today. It is production-ready, battle-tested, and the right choice when you need ORM integration beyond Drizzle (e.g., Prisma) or are working with an existing @libsql/client-based codebase.
With
@libsql/client Embedded Replicas, reads are local and writes are sent to the cloud primary, then reflected back to the replica. Embedded Replicas are fully supported. For new projects that need sync, we recommend @tursodatabase/sync with Turso Sync.Installing
Begin by installing the@libsql/client dependency in your project:
Initializing
If you’re using libsql locally or an sqlite file, you can ignore passing
authToken.In-Memory Databases
Local Development
You can work locally using an SQLite file and passing the path tocreateClient:
Embedded Replicas
For workloads that need offline writes, bidirectional sync, or multi-writer convergence, we recommend
@tursodatabase/sync — both reads and writes are local, and you sync explicitly with push() / pull().syncUrl:
Manual Sync
Periodic Sync
Encryption
TypeScript
Concurrency
By default, the client performs up to20 concurrent requests:
Response
Each method listed below returns aPromise<ResultSet>:
| Property | Type | Description |
|---|---|---|
rows | Array<Row> | An array of Row objects containing the row values, empty for write operations |
columns | Array<string> | An array of strings with the names of the columns in the order they appear in each Row, empty for write operations |
rowsAffected | number | The number of rows affected by a write statement, 0 otherwise |
lastInsertRowid | bigint | undefined | The ID of a newly inserted row, or undefined if there is none for the statement |
Simple query
You can pass a string or object toexecute() to invoke a SQL statement:
Placeholders
libSQL supports the use of positional and named placeholders within SQL statements:libSQL supports the same named placeholder characters as SQLite —
:, @ and $.Transaction Modes
| Mode | SQLite command | Description |
|---|---|---|
write | BEGIN IMMEDIATE | The transaction may execute statements that read and write data. Write transactions executed on a replica are forwarded to the primary instance, and can’t operate in parallel. |
read | BEGIN TRANSACTION READONLY | The transaction may only execute statements that read data (select). Read transactions can occur on replicas, and can operate in parallel with other read transactions. |
deferred | BEGIN DEFERRED | The transaction starts in read mode, then changes to write as soon as a write statement is executed. This mode change may fail if there is a write transaction currently executing on the primary. |
Batch Transactions
Usebatch() to send several SQL statements in a single call. Each item is either a SQL string or a { sql, args } object:
mode as the second argument to run the batch atomically. The statements are wrapped in BEGIN <mode> and COMMIT (rolling back on any failure) and dispatched as a single request, so the whole batch completes in one round trip:
mode accepts the same values as transaction(): "deferred", "immediate", "exclusive", and "concurrent". Each maps to the matching BEGIN <mode> statement. When batch() runs inside a transaction() callback, the mode argument is ignored and the surrounding transaction is reused.
batch() resolves to an object with rowsAffected (the total number of rows affected across every statement) and lastInsertRowid (the rowid of the last successful insert).
Interactive Transactions
Interactive transactions in SQLite ensure the consistency of a series of read and write operations within a transaction’s scope. These transactions give you control over when to commit or roll back changes, isolating them from other client activity.| Method | Description |
|---|---|
execute() | Similar to execute() except within the context of the transaction |
commit() | Commits all write statements in the transaction |
rollback() | Rolls back the entire transaction |
close() | Immediately stops the transaction |
ATTACH
You can attach multiple databases to the current connection using theATTACH attachment:
Make sure to allow
ATTACH and create a token
with the permission to attach a database — learn
more