TypeScript / JavaScript SDK
Package: @heliosdb/client (REST/Realtime, Supabase-compatible) or pg / postgres / node-postgres (direct PG wire)
Repo: heliosdb-sdks
Compatible with: Path B (PostgreSQL wire) works with every HeliosDB edition (Nano, Lite, Full); Path A targets Nano’s REST, auth and realtime surface
UVP
Two valid paths from Node.js / TypeScript into HeliosDB Nano: the @heliosdb/client package for a Supabase-compatible fluent API (db.from('table').select()) backed by REST + WebSocket, or the standard pg / postgres / Drizzle / Prisma stack for direct PostgreSQL-wire access. Both work against the same data; pick by use case. No proprietary driver required. This page shows hands-on snippets for each path — connect, CRUD, vector search — and links to a full end-to-end app tutorial.
Path A — REST + Realtime (@heliosdb/client)
Idiomatic for Next.js / Astro / SvelteKit apps that already know Supabase.
Install
# @heliosdb/client is not published on npm; build it from sourcegit clone https://github.com/HeliosDatabase/HeliosDB-SDKs.git(cd HeliosDB-SDKs/sdks/typescript && npm install && npm run build)npm install ./HeliosDB-SDKs/sdks/typescriptConnect
import { createClient } from "@heliosdb/client";
const db = createClient( "http://localhost:8080", "anon-key" // any string before login);Auth
// Signupconst { data: signupData } = await db.auth.signUp({ email: "alice@example.com", password: "s3cret",});
// Login (returns a session attached to the client)const { data: { session } } = await db.auth.signInWithPassword({ email: "alice@example.com", password: "s3cret",});console.log("access_token:", session.access_token);CRUD
// Insertconst { data: post } = await db .from("posts") .insert({ title: "Hello Nano", body: "First post" }) .select() .single();
// Read with filter chainconst { data: recent } = await db .from("posts") .select("id, title, body, created_at") .ilike("title", "%nano%") .gte("created_at", "2026-04-01") .order("created_at", { ascending: false }) .range(0, 9); // first 10 rows
// Updateawait db.from("posts") .update({ body: "edited" }) .eq("id", post.id);
// Deleteawait db.from("posts").delete().eq("id", post.id);Nano’s REST filters support eq, neq, gt, gte, lt, lte, like, ilike, is and in, with not. negation; cs, cd, ov, full-text and or/and filters are planned. The client’s chain methods for the planned operators fail against the current release.
Vector Search
const results = await db.vectorSearch("docs", [0.1, 0.2, 0.3, /* ...384 dims... */], { topK: 10, metric: "cosine", // "cosine" | "l2" | "ip" filter: { category: "tech" },});
for (const hit of results) { console.log(hit.id, hit.score, hit.row.title);}Realtime
const channel = db .channel("posts-changes") .on( "postgres_changes", { event: "*", schema: "public", table: "posts" }, (payload) => { console.log(payload.eventType, payload.new ?? payload.old); } ) .subscribe();
// channel.unsubscribe() to stopOpens ws://localhost:8080/realtime/v1/websocket and emits the same event shape Supabase does. Known issue: realtime events are not delivered in the current release; tracked by the Nano team. Realtime subscriptions are not filtered by row-level security: a subscriber receives every change on the tables it subscribes to. Secured realtime is planned.
Path B — Direct PG Wire (postgres / pg / Drizzle / Prisma)
Idiomatic for backend services with heavy SQL, transactions, or ORM usage.
postgres (porsager/postgres)
npm install postgresimport postgres from "postgres";
const sql = postgres("postgresql://postgres:s3cret@127.0.0.1:5432/postgres");
// Tagged-template parameters (auto-escaped)const users = await sql`SELECT id, name FROM users WHERE age > ${18}`;
await sql` INSERT INTO users (name, age) VALUES (${"Alice"}, ${30})`;
await sql.end();pg (node-postgres)
npm install pgimport { Pool } from "pg";
const pool = new Pool({ connectionString: "postgresql://postgres:s3cret@127.0.0.1:5432/postgres",});
const { rows } = await pool.query( "SELECT id, title FROM posts WHERE author = $1", ["alice@example.com"],);console.log(rows);
await pool.end();Drizzle ORM
import { drizzle } from "drizzle-orm/node-postgres";import { Pool } from "pg";import { pgTable, serial, text, timestamp } from "drizzle-orm/pg-core";
const posts = pgTable("posts", { id: serial("id").primaryKey(), title: text("title").notNull(), body: text("body"), createdAt: timestamp("created_at").defaultNow(),});
const pool = new Pool({ connectionString: "postgresql://postgres:s3cret@127.0.0.1:5432/postgres" });const db = drizzle(pool);
const [row] = await db.insert(posts).values({ title: "Hi", body: "..." }).returning();const all = await db.select().from(posts).limit(50);Drizzle (and Prisma) work without modification: the fixes recorded in the changelog address every Drizzle edge case (quoted identifiers, mixed-qualifier GROUP BY, parameterized LIMIT/OFFSET, timestamp wire format).
Vector Search via PG Wire
// Numbers only, so the literal cannot carry SQL.function vecLit(v: number[]): string { return "'[" + v.map(x => Number(x).toFixed(6)).join(",") + "]'";}
const qVec = [/* 384 dims */];
const { rows } = await pool.query( `SELECT id, title, embedding <=> ${vecLit(qVec)}::vector AS distance FROM docs ORDER BY distance LIMIT $1`, [5],);The query vector is inlined as a '[...]'::vector literal. In the current release a ::vector
cast on a bound parameter ($1::vector) fails; only inline literals work
(#33, see
Known Limitations).
When to Pick Which
| Need | Use |
|---|---|
| Frontend / serverless function | Path A (@heliosdb/client) |
| Realtime subscriptions | Known issue (tracked) |
| Drop-in Supabase migration | Path A |
| Drizzle / Prisma / TypeORM | Path B (pg / postgres) |
Bulk import (COPY FROM) | Path B |
| Heavy transactional workload | Path B |
| Multi-tenant RLS | Neither in the stock server: enforce per-user access in your service layer (SQL CREATE POLICY and RLS for REST and wire clients are planned) |
You can mix both in one repo — REST/Realtime for the API edge, Drizzle for batch jobs and migrations.
Next Steps
- NODEJS_BAAS_APP — full TypeScript app, REST + Realtime.
- BAAS_REST_API_TUTORIAL — REST endpoints at the curl level.
- Python SDK — same surface in Python.
- Go SDK — Go via PG wire.