Skip to content

Server setup

The generator emits a createRouter factory. You provide a Postgres client; it returns a Hono router with every table’s routes mounted. Import paths below assume the default outDir.

import { Hono } from "hono";
import { serve } from "@hono/node-server";
import { Client } from "pg";
import { createRouter } from "./api/server/router";
const app = new Hono();
const pg = new Client({ connectionString: process.env.DATABASE_URL });
await pg.connect();
app.route("/", createRouter({ pg }));
serve({ fetch: app.fetch, port: 3000 });

Routes are prefixed with apiPathPrefix (default /v1).

The generated code works with any client exposing a simple query interface.

// Node.js pg driver
import { Client } from "pg";
const pg = new Client({ connectionString: process.env.DATABASE_URL });
await pg.connect();
const router = createRouter({ pg });
// Neon serverless driver (edge-compatible)
import { Pool } from "@neondatabase/serverless";
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
const router = createRouter({ pg: pool });

onRequest runs before every operation — ideal for audit session variables or Row-Level Security. It receives the Hono Context (fully typed) and the pg client.

const router = createRouter({
pg,
onRequest: async (c, pg) => {
const auth = c.get("auth");
if (auth?.kind === "jwt" && auth.claims?.sub) {
await pg.query(`SET LOCAL app.user_id = '${auth.claims.sub}'`);
}
},
});

Auth is configured in postgresdk.config.ts. See the full shape in the Configuration reference.

postgresdk.config.ts
export default {
connectionString: "...",
auth: { apiKey: process.env.API_KEY },
};
// client
const sdk = new SDK({ baseUrl, auth: { apiKey: process.env.API_KEY } });

Secrets must use the env: prefix — the generator rewrites "env:JWT_SECRET" to process.env.JWT_SECRET in the generated code. Never inline a literal secret.

postgresdk.config.ts
export default {
connectionString: "...",
auth: {
jwt: {
services: [
{ issuer: "web-app", secret: "env:WEB_APP_SECRET" },
{ issuer: "mobile-app", secret: "env:MOBILE_SECRET" },
],
audience: "my-api", // optional: validates the aud claim
},
},
};
// client — the JWT must include an `iss` claim matching a configured service
const sdk = new SDK({ baseUrl, auth: { jwt: "eyJhbGciOiJIUzI1NiIs..." } });

For service-to-service authorization, put scopes in JWT claims and enforce them in onRequest rather than in config.