Turso is joining Supabase to give every agent its own database Read the news →

Turso for TypeScript.

SQLite that runs everywhere your TypeScript does.

query.ts
Turso
import { createClient } from '@tursodatabase/api';

const db = createClient({
  url: process.env.TURSO_URL!,
  authToken: process.env.TURSO_TOKEN!,
});

const result = await db.execute(
  'SELECT * FROM products WHERE id = ?',
  [id],
);

Turso is a SQLite-compatible database that runs in the last place SQLite usually can't: your edge functions. One driver works across Workers, Deno Deploy, Bun, and Node. You ship the same code everywhere.

Your first query takes three lines

Install one package, connect with a URL and token, and run your first query. The API is intentionally minimal – it does not add abstractions on top of SQL.

query.ts
Turso
import { createClient } from '@tursodatabase/api';

const db = createClient({
  url: process.env.TURSO_URL!,
  authToken: process.env.TURSO_TOKEN!,
});

const result = await db.execute(
  'SELECT * FROM products WHERE id = ?',
  [id],
);

Where SQLite stops, Turso keeps going

Putting SQLite in production hits the same walls every time. Turso was built to take those walls down.

01

Edge runtimes

Runs on Workers, Vercel Edge and Deno Deploy

The HTTP-based driver has zero native dependencies. It runs wherever you can make a fetch request, including V8 isolates that ban Node.js APIs.

worker.ts
Turso
import { createClient } from '@tursodatabase/api';

// Runs on Cloudflare Workers, Vercel Edge, Deno Deploy
export default {
  async fetch(req: Request): Promise<Response> {
    const db = createClient({
      url: env.TURSO_URL,
      authToken: env.TURSO_TOKEN,
    });
    const { rows } = await db.execute('SELECT * FROM items');
    return Response.json(rows);
  },
};

02

Offline

Your app keeps working offline

Embedded sync lets your app read from a local replica and write offline. Changes sync to the cloud the next time the device is online.

sync.ts
Turso
import { createClient } from '@tursodatabase/sync';

const db = createClient({
  url: 'file:local.db',
  syncUrl: process.env.TURSO_URL!,
  authToken: process.env.TURSO_TOKEN!,
});

// Sync latest writes from the cloud
await db.sync();

// Reads hit local storage; writes sync when online
const result = await db.execute('SELECT * FROM notes');

03

Concurrent writes

Many writers, one database

libSQL uses optimistic concurrency so multiple clients can write simultaneously without the serialization bottleneck of classic SQLite.

concurrent.ts
Turso
import { createClient } from '@tursodatabase/api';

const db = createClient({ url, authToken });

// Multiple writers at the same time via optimistic concurrency
await Promise.all([
  db.execute('INSERT INTO events VALUES (1, "login")'),
  db.execute('INSERT INTO events VALUES (2, "view")'),
  db.execute('INSERT INTO events VALUES (3, "buy")'),
]);

04

Multi-tenancy

A database for every user, tenant or agent

The platform API lets you spin up isolated databases in milliseconds. Each database shares a schema from a parent and stays isolated at the row level.

tenant.ts
Turso
import { createClient } from '@tursodatabase/api';

const turso = createClient({
  org: process.env.TURSO_ORG!,
  token: process.env.TURSO_PLATFORM_TOKEN!,
});

// Isolated database per tenant, spun up in milliseconds
const db = await turso.databases.create(
  `tenant-${tenantId}`,
  { group: 'prod', schema: 'main-schema' },
);

Bring Drizzle

Use the Drizzle Turso adapter to keep the query-builder ergonomics you already know. Schema migrations, type-safe queries, and relations all work the same way.

Read the Turso Drizzle docs
drizzle.ts
Turso
import { drizzle } from 'drizzle-orm/libsql';
import { createClient } from '@tursodatabase/api';

const client = createClient({ url, authToken });
const db = drizzle(client);

// Type-safe queries with your existing Drizzle schema
const users = await db
  .select()
  .from(schema.users)
  .where(eq(schema.users.active, true));
Also works with Kysely, Prisma, and any library that accepts a libSQL client.

Pick your package by where your code runs

Turso ships three TypeScript packages. Most apps need one.

@tursodatabase/api (HTTP)

The default choice for edge runtimes and serverless. Stateless, fetch-based, zero native deps. Works everywhere.

@tursodatabase/database (embedded)

Embeds libSQL as a native module. Use this for Node.js apps that need offline reads or embedded replicas.

@tursodatabase/sync (local-first)

Extends the embedded package with two-way sync. Ideal for local-first apps that read from device storage and sync to the cloud.

“Because we can branch and rollback databases quickly with just an API call, we can really scale our AI agents.”

Mike Soylu

Mike Soylu

Founder, Adaptive

Already in production, and moving fast

Open source

libSQL is MIT-licensed and developed in the open at github.com/tursodatabase/libsql.

In-house edge driver

The fetch-based driver is maintained by the Turso team. No third-party wrappers in the hot path.

Ready releases

SDK releases track the libSQL release cycle. Changelogs are public.

Questions TypeScript developers ask first

Which package should I use for my edge function?
Use @tursodatabase/api. It is stateless and fetch-based, so it works in any V8 isolate including Cloudflare Workers, Vercel Edge, and Deno Deploy.
Can I run local-first on Turso Cloud?
Yes. The @tursodatabase/sync package provides two-way sync between an embedded local database and Turso Cloud.
How much does an idle database cost?
An idle Turso database costs only storage. You don't pay for compute when no queries are running.
Is it ready for production?
Turso has been in production at thousands of companies since 2023. The edge driver is used in high-traffic production apps.
Can Turso run as a SQLite file locally?
Yes. Pass a local file path to @tursodatabase/database and it reads and writes a standard SQLite file you can inspect with any SQLite tool.

Install a package and run your first query.

100 databases free. Unlimited on paid plans.100 databases · 5 GB storage · 500M rows read