Two containers. That is it.
PostgreSQL + Rust proxy. No GoTrue, no PostgREST, no Realtime, no Kong, no Redis. Run docker compose up -d and your backend is ready.
Real-time SQL queries
The pg_reactive C extension turns any SELECT into a live subscription. Delta delivery via WebSocket. Column-level tracking. No polling.
PostgREST-compatible REST API
Full CRUD with PostgREST filter syntax — eq, gt,ilike, in, embedding via FK. Migrate from Supabase without changing client code.
Auth built-in
Email/password with argon2id, JWT (HS256), OAuth (Google, GitHub), refresh token rotation, and auto-refresh. RLS enforced on every request.
PostgreSQL-backed job queue
Durable background jobs and cron scheduling with no Redis or RabbitMQ. Jobs are rows. Failures are retried. Observability is a SELECT.
TypeScript SDK + CLI
Supabase-compatible @pgstack/sdk with React hooks. CLI for migrations, type generation, and dev environment management.
Get started in minutes
1. Start the stack
npx pgstack init my-app
cd my-app
docker compose up -d2. Query your data
import { createClient } from '@pgstack/sdk';
const db = createClient(
'http://127.0.0.1:8080',
process.env.PGSTACK_ANON_KEY,
);
const { data } = await db.from('todos')
.select('*')
.eq('done', false)
.order('created_at', { ascending: false });3. Subscribe to live updates
import { useLiveQuery } from '@pgstack/sdk/react';
function TodoList() {
const { rows, state } = useLiveQuery('active_todos', {
url: 'ws://127.0.0.1:8080',
token: session.access_token,
});
return rows.map(r => <li>{String(r.title)}</li>);
}4. Secure with RLS
ALTER TABLE todos ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users see own todos"
ON todos FOR ALL
USING (user_id = auth.uid());
-- Every REST request runs as the
-- authenticated PostgreSQL role.
-- RLS is automatic.