Use Turso (libSQL) with DaloyJS
Turso is a distributed database built on libSQL (a fork of SQLite). The @libsql/client driver speaks HTTP and WebSocket, so the same DaloyJS app works on Node, Bun, Deno, Cloudflare Workers, and Vercel Edge.
1. Provision
Create a database via the Turso CLI or dashboard, then grab the URL and auth token. Set them as TURSO_DATABASE_URL and TURSO_AUTH_TOKEN.
2. Install
pnpm add @libsql/client3. Create a Turso plugin
// src/db/turso.ts
import { createClient, type Client } from "@libsql/client";
import type { App } from "@daloyjs/core";
export const db: Client = createClient({
url: process.env.TURSO_DATABASE_URL!,
authToken: process.env.TURSO_AUTH_TOKEN,
});
export const tursoPlugin = {
name: "turso",
async register(app: App) {
app.decorate("db", db);
app.onClose(async () => {
db.close();
});
},
};4. Augment app state
// src/types/state.d.ts
import type { Client } from "@libsql/client";
declare module "@daloyjs/core" {
interface AppState {
db: Client;
}
}5. Use it in a route
import { z } from "zod";
import { App, secureHeaders } from "@daloyjs/core";
import { tursoPlugin } from "./db/turso";
const app = new App();
app.use(secureHeaders());
app.register(tursoPlugin);
const TodoSchema = z.object({ id: z.number(), title: z.string(), done: z.boolean() });
app.route({
method: "GET",
path: "/todos",
operationId: "listTodos",
responses: { 200: { description: "ok", body: z.array(TodoSchema) } },
handler: async ({ state }) => {
const result = await state.db.execute("select id, title, done from todos");
const rows = result.rows.map((r) => ({
id: Number(r.id),
title: String(r.title),
done: Boolean(r.done),
}));
return { status: 200, body: rows };
},
});Embedded replicas (Node, Bun)
For ultra-low-latency reads, use an embedded replica that syncs with the primary in the background. Writes still go to the primary; reads are local.
import { createClient } from "@libsql/client";
export const db = createClient({
url: "file:local.db",
syncUrl: process.env.TURSO_DATABASE_URL!,
authToken: process.env.TURSO_AUTH_TOKEN,
syncInterval: 60,
});Cloudflare Workers / Vercel Edge
Use the standard HTTP client (no embedded replicas in Workers). Pass env.TURSO_DATABASE_URL instead of process.env.
With Drizzle ORM
pnpm add drizzle-orm
// src/db/drizzle.ts
import { drizzle } from "drizzle-orm/libsql";
import { createClient } from "@libsql/client";
const client = createClient({
url: process.env.TURSO_DATABASE_URL!,
authToken: process.env.TURSO_AUTH_TOKEN,
});
export const db = drizzle({ client });With Prisma
Prisma supports Turso through the libSQL Driver Adapter in preview. Use Drizzle if you want a stable, production-ready setup today.
See also Cloudflare D1for a SQLite-style option that's bundled into Workers, or the database hosting overview.