What is Lazypock?
Lazypock is a self-hosted backend-as-a-service. It gives you a production REST API, realtime subscriptions, authentication, file storage, jobs and an admin Studio UI — without writing a line of backend code. Define your schema in the Studio and every collection instantly gets a full CRUD API, permissions and a realtime channel.
The backend is a single Rust binary on PostgreSQL — the API, auth, realtime, the TypeScript hooks runtime, the job queue and the Studio all ship in one artifact. Your app talks to it through one of the official SDKs.
The REST API is deliberately PocketBase-canonical, so existing PocketBase clients and SDKs point at it unchanged. Underneath it is real Postgres: real tables, real columns, and permissions enforced by Postgres row-level security.
What you get
🗄️ Dynamic collections
Create collections in Studio — real Postgres tables with real columns, instantly exposed over REST.
🔐 Auth
EdDSA tokens with refresh sessions and replay detection, OAuth2 providers, email verification, password reset, and lockout after repeated failures.
🛡️ Permissions as RLS
Collection rules compile to Postgres row-level security policies. Every request runs under a restricted role, denied by default.
⚡ Realtime
Subscriptions over SSE at /api/realtime, rule-filtered per subscriber, resumable from the last event id.
📁 File storage
Validated uploads, local + S3 backends, presigned direct upload, named image presets, and a media library with an orphan sweeper.
🪝 Hooks, cron & mail
TypeScript hooks in a sandboxed QuickJS runtime, hot-reloaded without a rebuild; a persisted cron scheduler and job queue; an SMTP mailer with templates.
📦 One binary, no sidecars
No Redis, no worker process, no image sidecar — Postgres is the source of truth and the message bus, so a node is one process.
🎨 Studio admin UI
Record browser, field editor, rules, indexes, API keys, logs, and import/export with backups — embedded in the binary.
Get started
Pick the path that matches what you're doing:
It looks like this
import { LazypockClient } from 'lazypock';
const client = new LazypockClient({ baseUrl: 'http://localhost:4000/api' });
await client.login('admin@example.com', 'password');
const posts = await client.collection('posts').getList(1, 30);
await client.collection('posts').create({ title: 'Hello', published: true });
client.collection('posts').subscribe((e) => console.log(e.action, e.record));License
Backend and Studio: MIT © 2024-2025 Chris Nguyen (gnuzd). The TypeScript SDK is MIT too.