L’interface est localisée ; les présentations et documents des Skills sont traduits automatiquement par IA dans votre langue. Le code, les commandes, chemins et termes techniques restent en version originale, et le document de l’auteur fait foi.
Explorer les Skills
Données et recherche · SKILL.md

libsql

libsql

Connects JavaScript and TypeScript apps to libSQL, the open-source SQLite fork behind Turso, with the @libsql/client SDK: local files, in-memory databases, remote Turso databases over libsql:// or HTTP, and embedded replicas that sync from the cloud. Use when a user asks for SQLite with remote sync, an edge-friendly SQL database, a Turso setup, or batches, …

Independent GitHub snapshot · Automated classification · Original documentation governs

Tterminalskills / skillsApache-2.0

Documentation de la Skill

GitHub

name: libsql description: >- Connects JavaScript and TypeScript apps to libSQL, the open-source SQLite fork behind Turso, with the @libsql/client SDK: local files, in-memory databases, remote Turso databases over libsql:// or HTTP, and embedded replicas that sync from the cloud. Use when a user asks for SQLite with remote sync, an edge-friendly SQL database, a Turso setup, or batches, transactions and parameterized queries with libSQL. license: Apache-2.0 compatibility: "Node.js 18+, Bun, Deno (via npm:). @libsql/client 0.18.x. Turso CLI for cloud databases." metadata: author: terminal-skills version: "1.1.0" category: development tags: ["libsql", "sqlite", "turso", "edge-database", "embedded"] repository: https://github.com/tursodatabase/libsql-client-ts

libSQL

Overview

libSQL is an open-source fork of SQLite that adds network access, replication and embedded replicas; Turso hosts it as a cloud database. The @libsql/client package (0.18.0 at the time of writing) talks to local SQLite files, in-memory databases and remote libSQL servers through one async API: execute, batch, transaction.

Turso also ships newer packages built on its Rust rewrite of SQLite: @tursodatabase/database (local, with concurrent writes), @tursodatabase/serverless (remote, no native dependencies) and @tursodatabase/sync. Turso's docs point to @libsql/client for ORM integration (Drizzle, Prisma) and for remote libSQL databases, and to @tursodatabase/sync instead of embedded replicas for new offline or bidirectional-sync work. Concurrent writes are not supported by @libsql/client.

Instructions

Installation and connection modes

npm install @libsql/client       # or: bun add @libsql/client
import { createClient } from "@libsql/client";

// Local SQLite file
const local = createClient({ url: "file:app.db" });

// In-memory (tests)
const memory = createClient({ url: ":memory:" });

// Turso cloud over libsql:// (WebSocket) or https:// (HTTP)
const cloud = createClient({
  url: process.env.TURSO_DATABASE_URL!,     // libsql://orders-prod-acme.turso.io
  authToken: process.env.TURSO_AUTH_TOKEN!,
});

Close a client with db.close() when finished. In edge runtimes without native bindings (Workers, Vercel Edge) import from @libsql/client/web, which supports only remote URLs, not file:.

Embedded replica

A local file that syncs from a remote Turso database: reads are local and fast, writes are sent to the remote primary.

const db = createClient({
  url: "file:replica.db",
  syncUrl: process.env.TURSO_DATABASE_URL!,
  authToken: process.env.TURSO_AUTH_TOKEN!,
  syncInterval: 60,        // seconds between automatic syncs
});
await db.sync();           // pull the latest changes now

Embedded replicas need a persistent filesystem, so they do not fit serverless functions or Workers.

Queries

await db.execute(`CREATE TABLE IF NOT EXISTS posts (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  title TEXT NOT NULL,
  slug TEXT UNIQUE NOT NULL,
  created_at INTEGER NOT NULL DEFAULT (unixepoch()))`);

const ins = await db.execute({
  sql: "INSERT INTO posts (title, slug) VALUES (?, ?)",
  args: ["Hello World", "hello-world"],
});
console.log(ins.lastInsertRowid, ins.rowsAffected);   // 1n 1

const found = await db.execute({ sql: "SELECT * FROM posts WHERE slug = :slug", args: { slug: "hello-world" } });
console.log(found.columns, found.rows[0].title);

Arguments are positional (? with an array) or named (:name with an object). A result has rows, columns, rowsAffected and lastInsertRowid. executeMultiple(sqlScript) runs a semicolon-separated script without parameters (migrations, seed files).

Batch and transactions

// One round trip, implicit transaction: all statements succeed or none do
const results = await db.batch([
  { sql: "INSERT INTO posts (title, slug) VALUES (?, ?)", args: ["Post 1", "post-1"] },
  { sql: "INSERT INTO posts (title, slug) VALUES (?, ?)", args: ["Post 2", "post-2"] },
  "SELECT COUNT(*) AS total FROM posts",
], "write");
console.log(results[2].rows[0].total);

// Interactive transaction: use when later statements depend on earlier results
const tx = await db.transaction("write");
try {
  await tx.execute({ sql: "UPDATE accounts SET balance = balance - ? WHERE user_id = ?", args: [100, 1] });
  await tx.execute({ sql: "UPDATE accounts SET balance = balance + ? WHERE user_id = ?", args: [100, 2] });
  await tx.commit();
} catch (err) {
  await tx.rollback();
  throw err;
} finally {
  tx.close();
}

Modes for batch and transaction: "write", "read" (read-only) and "deferred" (starts as a read, upgrades on first write). An interactive transaction holds a lock on the database, with a 5-second timeout on Turso, so keep it short.

Turso CLI

brew install tursodatabase/tap/turso          # macOS; Linux/WSL installer: docs.turso.tech/cli/installation
turso auth login
turso db create orders-prod
turso db show orders-prod --url               # libsql://orders-prod-<org>.turso.io
turso db tokens create orders-prod --read-only --expiration 7d
turso db shell orders-prod

turso db tokens create without flags makes a full-access token; prefer --read-only for read paths and an expiration for anything shared.

Examples

Example 1: "Add a Turso database to my Next.js app"

npm install @libsql/client
turso db create storefront-prod
turso db show storefront-prod --url
turso db tokens create storefront-prod
// lib/db.ts
import { createClient } from "@libsql/client";

if (!process.env.TURSO_DATABASE_URL) throw new Error("TURSO_DATABASE_URL is required");

export const db = createClient({
  url: process.env.TURSO_DATABASE_URL,
  authToken: process.env.TURSO_AUTH_TOKEN,
});

Put both values in .env.local. A query such as db.execute("SELECT COUNT(*) AS n FROM products") returns { n: 42 } in rows[0].

Example 2: "Insert a row and get it back"

const created = await db.execute({
  sql: "INSERT INTO posts (title, slug) VALUES (?, ?) RETURNING id, title, slug",
  args: ["Launch notes", "launch-notes"],
});
console.log(created.rows[0]);   // { id: 7, title: 'Launch notes', slug: 'launch-notes' }

With RETURNING, the new row comes back in rows; lastInsertRowid is undefined and rowsAffected is 0 on a local file (checked on 0.18.0), so read the id from the row.

Guidelines

  • Always pass values through args; never concatenate user input into SQL.
  • lastInsertRowid is a bigint for plain inserts; use Number() for small ids. Integers above 2^53 in a result throw RangeError unless the client is created with intMode: "bigint" (or "string").
  • Errors are LibsqlError with a code such as SQLITE_CONSTRAINT; check err.code, for example to turn a duplicate slug into a 409 response.
  • Use batch() for independent writes that must succeed together; use an interactive transaction() only when a later statement depends on an earlier result.
  • Keep TURSO_AUTH_TOKEN in the environment or a secrets manager, never in source or a browser bundle.
  • Embedded replicas are eventually consistent; call db.sync() before a read that must see recent remote writes.
  • Remote databases take one writer at a time; for write-heavy or multi-writer workloads, check Turso's newer @tursodatabase/* packages first.
  • ":memory:" gives every test an isolated database.
Skills enregistrées