L Lazypock
Backend · Rust + PostgreSQL SDK · TypeScript

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('[email protected]', '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.