01 |CHOOSE A CLIENT
One database, three ways to connect
Serverless and edge runtimes cannot open raw TCP sockets, so every client here speaks HTTP and WebSocket. The same code runs in a Worker, a function or a browser.
The JavaScript SDK, for SurrealQL
The surrealdb package speaks SurrealQL over HTTP or WebSocket, with the full data model: graph, vectors, live queries and record access.
Surqlize, for a type-safe query builder
Define tables once with t.* builders and get typed selects, writes, graph edges and live queries, with no code generation. It runs on the SDK.
SQL drivers, for SQL and your ORM
@surrealdb/pg and @surrealdb/mysql send PostgreSQL and MySQL SQL over HTTP and WebSocket, so they run where TCP sockets do not, and Drizzle and Kysely run on top.
02 |SURREALDB
The JavaScript SDK
The official client for SurrealQL. Connect over HTTPS from a Worker, one connection for each invocation, with a token in a secret.
Install
npm install surrealdb
Cloudflare Worker
1import { Surreal } from "surrealdb";
2
3interface Env {
4 SURREAL_URL: string; // https://abc123.surrealdb.earth
5 SURREAL_TOKEN: string;
6}
7
8export default {
9 async fetch(request: Request, env: Env): Promise<Response> {
10 // A connection per invocation: nothing to keep alive.
11 const db = new Surreal();
12
13 await db.connect(env.SURREAL_URL, {
14 namespace: "prod",
15 database: "app",
16 authentication: env.SURREAL_TOKEN,
17 });
18
19 try {
20 const [people] = await db
21 .query("SELECT name, age FROM person WHERE age > $min", { min: 18 })
22 .collect<[{ name: string; age: number }[]]>();
23
24 return Response.json(people);
25 } finally {
26 await db.close();
27 }
28 },
29};
Per-request identity
// The identity is whoever is asking, decided for every request.
await db.connect("https://abc123.surrealdb.earth", {
namespace: "prod",
database: "app",
authentication: {
resolve: () => requestContext.getStore()?.token ?? null,
when: "request",
},
});
WebSocket and records
import { RecordId, Surreal } from "surrealdb";
// A WebSocket for sessions and live queries, in Node, Bun, Deno or a browser.
const db = new Surreal();
await db.connect("wss://abc123.surrealdb.earth", {
namespace: "prod",
database: "app",
authentication: { username: "root", password: "root" },
});
await db.create(new RecordId("person", "tobie")).content({ name: "Tobie", age: 30 });
03 |SURQLIZE
Typed queries with Surqlize
A type-safe TypeScript ORM for SurrealDB. Tables are defined with t.* builders, and TypeScript infers every result type without code generation. It takes the same Surreal client.
Install
npm install surqlize surrealdb
Define, connect and query
1import { Surreal } from "surrealdb";
2import { orm, t, table } from "surqlize";
3
4const person = table("person", {
5 name: t.string(),
6 age: t.number(),
7 created: t.date().default(() => new Date()),
8});
9
10const surreal = new Surreal();
11await surreal.connect("https://abc123.surrealdb.earth", {
12 namespace: "prod",
13 database: "app",
14 authentication: { token: process.env.SURREAL_TOKEN },
15});
16
17const db = orm(surreal, person);
18
19await db.create("person").content({ name: "Ada", age: 36 });
20
21// The result type is inferred: { name: string; age: number }[]
22const adults = await db
23 .select("person")
24 .where((p) => p.age.gte(18))
25 .return((p) => ({ name: p.name, age: p.age }));
Surqlize targets SurrealDB 3 and later, and needs the surrealdb SDK 2.1 or later installed beside it, as one copy.
04 |SURREALDB POSTGRES AND MYSQL
SQL drivers for the edge
@surrealdb/pg and @surrealdb/mysql run PostgreSQL and MySQL SQL against SurrealDB over HTTP and WebSocket. Values in a template are bound as typed parameters, never interpolated into the text.
PostgreSQL
npm install @surrealdb/pg
1import { connect } from "@surrealdb/pg";
2
3const sql = connect("postgres://root:root@abc123.surrealdb.earth/app?namespace=prod");
4
5const name = "Tobie";
6const rows = await sql`SELECT name, age FROM person WHERE name = ${name}`;
7
8// Several statements in one request, all or nothing.
9const [created, count] = await sql.batch([
10 sql`INSERT INTO person (id, name) VALUES (${"a"}, ${"A"})`,
11 sql`SELECT count(*) FROM person`,
12]);
13
14// SurrealQL on the same connection, with the same namespace, database and auth.
15const graph = await sql.surql`SELECT ->authored->post.title AS posts FROM person`;
MySQL
npm install @surrealdb/mysql
1import { connect } from "@surrealdb/mysql";
2
3const sql = connect("mysql://root:root@abc123.surrealdb.earth/app?namespace=prod");
4
5const name = "Tobie";
6const rows = await sql`SELECT name, age FROM person WHERE name = ${name}`;
7
8// An interactive transaction runs over a WebSocket session.
9await sql.begin(async (tx) => {
10 await tx`UPDATE account SET balance = balance - ${10} WHERE id = ${"x"}`;
11 await tx`UPDATE account SET balance = balance + ${10} WHERE id = ${"y"}`;
12});
Bring your ORM
// Drizzle on PostgreSQL
import { Pool } from "@surrealdb/pg";
import { drizzle } from "drizzle-orm/node-postgres";
const pool = new Pool({ connectionString: env.SURREAL_PG_URL });
const db = drizzle({ client: pool as never });
// Kysely on MySQL
import { createPool } from "@surrealdb/mysql/callback";
import { Kysely, MysqlDialect } from "kysely";
const db = new Kysely({
dialect: new MysqlDialect({ pool: createPool({ uri: env.SURREAL_MYSQL_URL }) as never }),
});
Connection options
connect({
url: "surrealdb+wss://abc123.surrealdb.earth/prod/app",
auth: { username: "root", password: "..." }, // or { token } or () => token
transport: "auto", // "http" | "ws"
timeout: 15_000,
});
05 |GOOD TO KNOW
Runtimes, transports and credentials
Where each one runs
All three use fetch, WebSocket and AbortController, and no Node built-ins. They run on Cloudflare Workers, Vercel Edge, Deno Deploy, Bun, Node 20 and later, and in browsers. Node versions without a global WebSocket need one passed in, for example from ws.
HTTP for one call, WebSocket for a session
One-shot queries go over HTTP, with no handshake, which is the lowest latency from a cold isolate. Interactive transactions and live queries open a WebSocket. The SQL drivers choose for you with transport auto.
Tokens, not passwords, in the client
Give each client a token, or a function that returns one. Never put root credentials in browser code. Record access and permissions decide what a token may read and write.
TRUSTED BY
Enterprise teams building on SurrealDB
JavaScript,answered
THE PLATFORM
Everything an application and its agents know. Five surfaces, one engine.
Database
Document, graph, vector, time-series and relational in one engine.

Agent Memory
What an agent learns, with its source and its time, in the same engine.

Cloud
Dedicated clusters by region, or serverless on SurrealDB Earth.

Studio
Query, explore and design the schema from the browser.

MCP
Every model that speaks MCP reaches the database and the memory directly.

IN PRODUCTION
Trusted at scale. Samsung, Nvidia, Verizon, Tencent, and Walmart run on SurrealDB.
14,000+
Developers building on SurrealDB Cloud
4M+
Developers building on SurrealDB worldwide
FROM THE TEAMS
SurrealDB gives us a foundation where we can unify semantic search, knowledge graphs, and AI-driven decision making without stitching together multiple systems. Collapsing responsibility into SurrealDB has become our default engineering posture.
VP of Engineering, Later
GET STARTED




