Docs
Connecting

Frameworks

Connect Next.js, Nuxt, SvelteKit, and TanStack apps to Silos — over a standard Postgres connection or an SDK adapter.

You can use Silos from any web framework two ways:

  1. As a standard Postgres database — point your driver or ORM at the connection string. This always works.
  2. Through a Silos SDK adapter — framework-specific packages (@silos/next, @silos/nuxt, @silos/svelte, @silos/tanstack) that wrap the connection for that framework's conventions.

The SDK adapter packages exist for these frameworks, but we haven't published per-framework integration tests. If you want the most predictable path today, connect with a standard Postgres driver or ORM. Treat the adapters as convenience wrappers, not a different protocol.

The portable approach: a standard Postgres connection

Every framework can call Postgres from server code. Use a driver or ORM with your DATABASE_URL and you're done.

app/lib/db.ts
import { Pool } from 'pg'

export const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
  ssl: { rejectUnauthorized: true },
})
app/page.tsx
import { pool } from './lib/db'

export default async function Page() {
  const { rows } = await pool.query('SELECT now()')
  return <pre>{JSON.stringify(rows[0])}</pre>
}

Query from Server Components, Route Handlers, or Server Actions. For a serverless or edge runtime where a long-lived TCP pool isn't ideal, use SQL over HTTP instead.

server/utils/db.ts
import { Pool } from 'pg'

export const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
  ssl: { rejectUnauthorized: true },
})
server/api/now.get.ts
import { pool } from '../utils/db'

export default defineEventHandler(async () => {
  const { rows } = await pool.query('SELECT now()')
  return rows[0]
})

Use the pool from Nitro server routes (server/api/...).

src/lib/server/db.ts
import { Pool } from 'pg'
import { DATABASE_URL } from '$env/static/private'

export const pool = new Pool({
  connectionString: DATABASE_URL,
  ssl: { rejectUnauthorized: true },
})
src/routes/+page.server.ts
import { pool } from '$lib/server/db'

export async function load() {
  const { rows } = await pool.query('SELECT now()')
  return { now: rows[0] }
}

Keep the connection in $lib/server so it stays server-only.

src/server/db.ts
import { Pool } from 'pg'

export const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
  ssl: { rejectUnauthorized: true },
})
src/routes/index.tsx
import { createServerFn } from '@tanstack/react-start'
import { pool } from '../server/db'

const getNow = createServerFn().handler(async () => {
  const { rows } = await pool.query('SELECT now()')
  return rows[0]
})

Query from a server function so the connection never reaches the client.

SDK adapter packages

For convenience, Silos publishes framework adapter packages:

FrameworkPackage
Next.js@silos/next
Nuxt@silos/nuxt
SvelteKit@silos/svelte
TanStack@silos/tanstack

These wrap the underlying connection for each framework's data-fetching conventions. They connect to the same database over the same protocol as a raw driver — so if an adapter isn't a fit, you can always drop down to a standard Postgres connection.

Keep all database access in server-side code. A connection string is a secret and must never reach the browser.

Next steps

On this page