Skip to main content
Turso offers three TypeScript packages: Starting a new project? Use @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

In-memory databases are also supported:

Querying

Encryption

Encrypt local databases at rest using the encryption option:
Supported ciphers: 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; use push() to send changes to the cloud and pull() to fetch remote changes.

Installing

Initializing

On the first run, the local database is automatically bootstrapped from the remote. See Turso Sync for full details.

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 only fetch — zero native dependencies, works everywhere fetch is available.

Installing

Initializing

For compatibility with the @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 to createClient:
The @libsql/client/web does not support local file URLs.

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().
You can work with embedded replicas by passing your Turso Database URL to syncUrl:
Embedded Replicas only works where you have access to the file system.

Manual Sync

Periodic Sync

Encryption

For new projects, we recommend @tursodatabase/database for local encryption — it is built on the Turso Database engine with better performance and concurrent write support.
TypeScript
Encrypted databases appear as raw data and cannot be read as standard SQLite databases. You must use the libSQL client for any operations — learn more.

Concurrency

By default, the client performs up to 20 concurrent requests:

Response

Each method listed below returns a Promise<ResultSet>:

Simple query

You can pass a string or object to execute() 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

Batch Transactions

Use batch() to send several SQL statements in a single call. Each item is either a SQL string or a { sql, args } object:
By default a batch is not transactional. Each statement runs in its own autocommit step, so a failure partway through leaves the statements that already succeeded committed. Pass a 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).
When you pass a mode, batch() manages the surrounding BEGIN, COMMIT, and ROLLBACK. Do not include your own transaction-control statements (BEGIN, COMMIT, ROLLBACK, SAVEPOINT, RELEASE) in the batch.

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.

Interactive transactions in libSQL lock the database for writing until committed or rolled back, with a 5-second timeout. They can impact performance on high-latency or busy databases.

ATTACH

You can attach multiple databases to the current connection using the ATTACH attachment:
Make sure to allow ATTACH and create a token with the permission to attach a database — learn more