Skip to content

Examples

PerSQL uses @persql/sdk and nothing else fancy — no ORM, no API gateway, no edge tricks. The same one-import shape works for Next.js, Hono, SvelteKit, or any server-rendered framework.

Every project follows the same shape:

import { PerSQL } from "@persql/sdk";
const persql = new PerSQL({ token: process.env.PERSQL_TOKEN! });
export const db = persql.database(process.env.PERSQL_DATABASE!);
// Then, anywhere on the server:
const { data } = await db.query<Row>("SELECT * FROM things WHERE id = ?", [id]);

No connection pool, no driver to ship to the edge, no migrations framework to wire up. The SDK makes one HTTPS request per call.

"use server";
import { db } from "@/lib/db";
export async function addTodo(title: string) {
await db.query("INSERT INTO todos (title) VALUES (?)", [title]);
}
export async function listTodos() {
const { data } = await db.query<{ id: number; title: string }>(
"SELECT id, title FROM todos ORDER BY id DESC",
);
return data;
}
import { Hono } from "hono";
import { db } from "./db";
const app = new Hono();
app.post("/links", async (c) => {
const { url } = await c.req.json();
const slug = crypto.randomUUID().slice(0, 7);
await db.query("INSERT INTO links (slug, url) VALUES (?, ?)", [slug, url]);
return c.json({ slug });
});
app.get("/:slug", async (c) => {
const { data } = await db.query<{ url: string }>(
"SELECT url FROM links WHERE slug = ?", [c.req.param("slug")],
);
return data[0] ? c.redirect(data[0].url) : c.notFound();
});
export default app;
import { db } from "$lib/server/db";
import type { PageServerLoad } from "./$types";
export const load: PageServerLoad = async ({ params }) => {
const { data } = await db.query<{ id: number; title: string; body: string }>(
"SELECT id, title, body FROM posts WHERE slug = ?", [params.slug],
);
if (!data[0]) throw error(404, "post not found");
return { post: data[0] };
};

Make a database in the console, create a token (Tokens → New token), set PERSQL_TOKEN and PERSQL_DATABASE (in the form namespace/db) in your .env, then apply your schema by pasting CREATE TABLE… into the console SQL editor or piping it via the CLI. That’s the whole setup — no migrations framework, no driver to install.

  • Drizzle if you want types and a query builder. The SDK exposes a drizzle-orm/sqlite-proxy driver via db.driver().
  • Tool use to expose the same database as a callable tool to Claude or GPT.
  • Local mode to run the SDK against :memory: in tests.