Skip to content
STACK IT FAST

PocketBase

Curated OSSClassicEmbedded BackendSolo

Audited from github.com/pocketbase/pocketbase

PocketBase is an open-source real-time backend in a single file, combining embedded SQLite, user authentication, file storage, and an admin dashboard.

Language
Go
Database
SQLite
License
MIT
Running for
3 years
Team
Solo

Why this architecture

Distributing as a single statically linked binary eliminates microservice operational overhead, running complete production workloads on minimal single-node hardware.

Tech stack by layer

4 technologies · audited Sep 17, 2026
Frontend & UI
  • JavaScriptClient-side application logic for the embedded superuser admin UI in ui/src.
  • ViteBundles the admin panel frontend into pre-minified static assets compiled into ui/dist.
  • LeafletInteractive map viewer for spatial and geographical point fields in the admin dashboard.
Backend & APIs
  • GoSingle-binary application runtime, CLI orchestration via Cobra, and HTTP request dispatching.
  • GojaEmbedded ECMAScript 5.1/2015+ JavaScript runtime allowing custom backend hooks and JS scripts.
Data & Persistence
  • SQLiteEmbedded database operated in WAL mode via modernc.org/sqlite without CGO requirements.
  • S3Optional S3-compatible cloud storage adapter for user file uploads alongside local disk storage.
Infrastructure & Deploy
  • GoReleaserAutomates multi-architecture cross-compilation binaries for Linux, macOS, FreeBSD, and Windows.

PocketBase architecture diagram

Open SVG
PocketBase architecture diagramYour app → pocketbase binary (REST · auth); Your app → Realtime (subscribe); Admin UI → pocketbase binary (superuser API); pocketbase binary → Hooks (events); pocketbase binary → SQLite (query builder); pocketbase binary → File storage (uploads)CLIENTSSERVICESWORKERS & JOBSDATA & STORAGEYour appREST · SSE clientsAdmin UIVite · embedded in binarypocketbase binaryGo · custom routerRealtimeServer-Sent EventsHooksGo · Goja JS VMSQLiteWAL · modernc (no CGO)File storagelocal disk or S3REST · authsubscribesuperuser APIeventsquery builderuploads
How the main components of PocketBase connect, drawn from the audited repository.
Diagram as text
  • Your app (REST · SSE clients) → pocketbase binary (Go · custom router): REST · auth
  • Your app (REST · SSE clients) → Realtime (Server-Sent Events): subscribe
  • Admin UI (Vite · embedded in binary) → pocketbase binary (Go · custom router): superuser API
  • pocketbase binary (Go · custom router) → Hooks (Go · Goja JS VM): events
  • pocketbase binary (Go · custom router) → SQLite (WAL · modernc (no CGO)): query builder
  • pocketbase binary (Go · custom router) → File storage (local disk or S3): uploads

Key architectural decisions

5 decisions
  1. 01

    Pure Go SQLite driver eliminates CGO compile-time dependencies

    PocketBase depends on modernc.org/sqlite rather than mattn/go-sqlite3, allowing static compilation with CGO_ENABLED=0 across dozens of CPU architectures without C toolchain cross-compilers.

  2. 02

    Embedded admin UI compiles directly into the Go binary

    The web dashboard in ui/ is pre-built with Vite and embedded via Go embed directives in ui/embed.go, delivering a functional single-executable backend without external asset hosting.

  3. 03

    Server-Sent Events for real-time subscription channels

    Real-time record subscriptions (apis/realtime.go) operate over HTTP Server-Sent Events (SSE) instead of WebSockets, simplifying reverse proxy configurations and HTTP/2 multiplexing.

  4. 04

    Goja embedded JS VM for zero-recompile hook extensions

    The jsvm plugin (plugins/jsvm) embeds the Goja JavaScript engine, enabling developers to write backend hooks, validation logic, and scheduled cron jobs in JavaScript files without recompiling Go.

  5. 05

    Elimination of third-party HTTP frameworks in favor of custom router

    PocketBase removed external routing frameworks like Echo, replacing them with an internal router (tools/router) built directly upon Go standard library HTTP patterns.

How PocketBase is built

How PocketBase is structured

PocketBase is engineered as a monolithic Go library and CLI tool that packages an embedded database, file storage manager, authentication system, real-time subscription engine, and administrative dashboard into a single portable binary. The repository is organized into distinct domain layers:

  • core/: Contains the fundamental application kernel (core/app.go), database connection pooling and query builder abstractions (core/db.go), record validation models, migrations manager (core/migrations_runner.go), and event hook infrastructure (core/events.go).
  • apis/: Exposes HTTP handlers for record CRUD operations (apis/record_crud.go), authentication methods including OAuth2 and MFA (apis/record_auth.go), file upload serving, batch requests, and real-time Server-Sent Events endpoints (apis/realtime.go).
  • tools/: Independent utility packages covering routing (tools/router), filesystem access and S3 integration (tools/filesystem), JWT token handling, security utilities, and subscription managers.
  • ui/: The browser-based superuser admin interface, packaged with Vite and embedded directly into the Go executable through ui/embed.go.
  • plugins/: Optional extensions such as the embedded JavaScript runtime (plugins/jsvm) and automatic schema migration CLI commands (plugins/migratecmd).

Frontend

The administrative UI in ui/ allows administrators to configure collections, manage users, inspect API logs, and test database rules interactively. The frontend is bundled using Vite 8 (ui/package.json) and compiled into ui/dist/.

The admin application uses native JavaScript and CSS combined with specialized components such as Leaflet (leaflet version 1.9.4) for rendering geographic and point fields on interactive maps. Pre-built frontend bundles are committed to the repository and compiled directly into the binary using Go's //go:embed functionality in ui/embed.go. For headless deployments or resource-constrained environments, ui/embed_no_ui.go provides build tags to exclude the admin panel entirely.

Backend & APIs

The backend server is implemented in Go 1.27 (go.mod). Rather than relying on external web frameworks like Echo or Gin, modern PocketBase utilizes a specialized HTTP routing package (tools/router) that wraps Go's standard library net/http primitives while offering route grouping, path parameter extraction, and middleware chaining.

Every HTTP interaction is wrapped in event hooks (core/event_request.go). Developers can register custom interceptor hooks—either programmatically in Go via app.OnRecordCreate() or through the JavaScript VM plugin (plugins/jsvm/). The JS VM plugin utilizes Goja (github.com/dop251/goja), allowing teams to author TypeScript or JavaScript files in pb_hooks/ that execute synchronously within the request pipeline without requiring Node.js.

Data & persistence

Persistence is anchored on embedded SQLite:

  • Database Engine: PocketBase uses modernc.org/sqlite, a pure Go transpilation of SQLite that runs without requiring CGO or native C library linking. The database runs with write-ahead logging (PRAGMA journal_mode=WAL) enabled, allowing concurrent read transactions while serializing writes cleanly.
  • Query Building: Database queries are formulated using github.com/pocketbase/dbx, a lightweight query builder that translates parameterized filters into optimized SQL statements.
  • File Storage: Uploaded attachments are managed through tools/filesystem. By default, files reside in local disk volumes (pb_data/storage), but the storage engine supports S3-compatible cloud backends (AWS S3, Cloudflare R2, MinIO) configured via admin settings or environment credentials.

Realtime / collaboration

Real-time synchronization in PocketBase is implemented over HTTP Server-Sent Events (apis/realtime.go, tools/subscriptions) rather than WebSockets. Clients connect to the /api/realtime endpoint, receiving a unique client ID.

When records are inserted, updated, or deleted, PocketBase evaluates the active subscriptions and applies collection-level API rules (row-level security) for the subscribed client. If the rule passes, an event containing the record payload is pushed immediately across the open SSE stream. This approach reduces connection complexity and works seamlessly through corporate proxies, firewalls, and HTTP/2 CDNs.

Build, test & deploy

  • Cross-Compilation: Build configurations in .goreleaser.yaml compile statically linked binaries for dozens of architectures (Linux x86_64, ARM64, RISC-V, macOS Apple Silicon and Intel, FreeBSD, and Windows).
  • Testing: The repository maintains automated test suites (tests/app.go, tests/api.go) covering authentication flows, transactional integrity, and rule evaluations executed via go test ./....
  • Deployment: Deploying PocketBase requires uploading the single executable and running ./pocketbase serve --http="0.0.0.0:8090". The only persistent state is the pb_data directory, which holds SQLite database files, logs, and local file uploads.

Self-hosting notes

Operating PocketBase in production is remarkably straightforward:

  1. Provision a single Linux server, virtual machine, or container (e.g., Fly.io, Hetzner, Railway).
  2. Attach a persistent volume for the pb_data/ directory to preserve SQLite databases and uploaded media.
  3. Run the binary as a systemd service or minimal Docker container.
  4. Set up TLS termination using a reverse proxy (Caddy, Nginx) or utilize PocketBase's built-in Let's Encrypt automated certificate manager.

What to copy (and what not to)

Architectural lessons from PocketBase:

  • Zero-dependency deployment: Eliminating CGO dependencies by choosing pure Go drivers allows true static binary distribution, drastically reducing operational friction and deployment complexity.
  • Pragmatic embedded databases: For many small-to-medium applications, embedded SQLite in WAL mode delivers microsecond query latencies and eliminates network round-trips to external database clusters.
  • SSE over WebSockets for unidirectional data push: Server-Sent Events offer a resilient, standard HTTP mechanism for streaming database mutations to clients without the framing and reconnection overhead of WebSockets.

Conversely, avoid using embedded SQLite architectures if your workload requires multi-region active-active writes or distributed multi-node horizontal scaling, as SQLite write locks are restricted to a single filesystem node.

Sources & repo audit

Audited
Sep 17, 2026
Commit
5cec579
License
MIT

Independent analysis of repository at github.com/pocketbase/pocketbase. Spotted an inaccuracy? Use the claim form to request a correction.

Show this stack on your README or website
Tech stack of PocketBase
[![Tech stack of PocketBase on STACK IT FAST](https://stackitfast.com/badge/pocketbase.svg)](https://stackitfast.com/project/pocketbase)

Paste it into your README. It shows your current stack and links to this page.

Use this stack

Scaffold it with your agent

Paste this prompt into Claude Code, Cursor, Windsurf or AGY to start a project with PocketBase's architecture.

  1. 1Copy the promptThe full markdown spec, with every layer and decision.
  2. 2Open your AI toolClaude Code, Cursor, Windsurf or Copilot, in a new repo.
  3. 3Paste and scaffoldUse it as the first instruction; review before you ship.
use-this-stack.md · 59 lines · 6.0 KB
# MISSION: Scaffold "PocketBase" Production Architecture
You are an expert Senior Staff Software Architect and Full-Stack Engineer. Your mission is to scaffold and implement a production-grade, highly reliable, and modular codebase following the proven architecture of **PocketBase**.
---
## 1. PROJECT SPECIFICATIONS & BENCHMARK
- **Reference Architecture**: PocketBase
- **What It Does**: PocketBase is an open-source real-time backend in a single file, combining embedded SQLite, user authentication, file storage, and an admin dashboard.
- **Domain & Category**: Embedded Backend
- **Production Scale**: Solo
- **Development Mode**: CLASSIC
- **Architectural Rationale**: Distributing as a single statically linked binary eliminates microservice operational overhead, running complete production workloads on minimal single-node hardware.
- **Live Website Reference**: https://pocketbase.io
- **Source Repository**: https://github.com/pocketbase/pocketbase
---
## 2. PRODUCTION TECH STACK
- **Full Stack Array**: Go, SQLite, JavaScript, Vite
- **Primary Language(s)**: Go, JavaScript, CSS
- **License of the reference repo**: MIT
- **Frontend**: JavaScript — Client-side application logic for the embedded superuser admin UI in ui/src.; Vite — Bundles the admin panel frontend into pre-minified static assets compiled into ui/dist.; Leaflet — Interactive map viewer for spatial and geographical point fields in the admin dashboard.
- **Backend & APIs**: Go — Single-binary application runtime, CLI orchestration via Cobra, and HTTP request dispatching.; Goja — Embedded ECMAScript 5.1/2015+ JavaScript runtime allowing custom backend hooks and JS scripts.
- **Data & persistence**: SQLite — Embedded database operated in WAL mode via modernc.org/sqlite without CGO requirements.; S3 — Optional S3-compatible cloud storage adapter for user file uploads alongside local disk storage.
- **Infrastructure & deploy**: GoReleaser — Automates multi-architecture cross-compilation binaries for Linux, macOS, FreeBSD, and Windows.
---
## 3. KEY ARCHITECTURAL DECISIONS (audited from https://github.com/pocketbase/pocketbase @ 5cec579)
1. **Pure Go SQLite driver eliminates CGO compile-time dependencies**: PocketBase depends on modernc.org/sqlite rather than mattn/go-sqlite3, allowing static compilation with CGO_ENABLED=0 across dozens of CPU architectures without C toolchain cross-compilers.
2. **Embedded admin UI compiles directly into the Go binary**: The web dashboard in ui/ is pre-built with Vite and embedded via Go embed directives in ui/embed.go, delivering a functional single-executable backend without external asset hosting.
3. **Server-Sent Events for real-time subscription channels**: Real-time record subscriptions (apis/realtime.go) operate over HTTP Server-Sent Events (SSE) instead of WebSockets, simplifying reverse proxy configurations and HTTP/2 multiplexing.
4. **Goja embedded JS VM for zero-recompile hook extensions**: The jsvm plugin (plugins/jsvm) embeds the Goja JavaScript engine, enabling developers to write backend hooks, validation logic, and scheduled cron jobs in JavaScript files without recompiling Go.
5. **Elimination of third-party HTTP frameworks in favor of custom router**: PocketBase removed external routing frameworks like Echo, replacing them with an internal router (tools/router) built directly upon Go standard library HTTP patterns.
---
## 4. NON-NEGOTIABLE ARCHITECTURAL GUARDRAILS
1. **Monorepo & Modular Separation**:
   - Structure as a Turborepo monorepo with strict package boundaries:
     - `apps/web`: Application UI, routing, layouts, and server endpoints.
     - `packages/ui`: Shared design tokens, CSS variables, and Radix UI primitive components.
     - `packages/db`: Database schemas, client singleton, declarative migrations, and seed scripts.
     - `packages/config`: Shared TypeScript, ESLint, and build configurations.
2. **Strict Type Safety & Zero `any` Policy**:
   - Enable `strict: true`, `noImplicitAny: true`, and `strictNullChecks: true`.
   - Validate ALL external inputs, API request bodies, and query parameters with **Zod** schemas before execution.
3. **Frontend & Rendering Guidelines**:
   - Utilize Vite 6 with TanStack Router for fully type-safe routing. Manage server state and caching via TanStack Query v5 with optimistic UI updates.
4. **Design System & Aesthetics**:
   - Keep every color, radius, shadow and font in a single token file (CSS variables) and consume tokens everywhere; never hardcode hex values in components.
   - Prefer crisp 1px borders and one subtle shadow scale over blurry default shadows. Pair one sans-serif for body/headings with one monospace for tags, badges, metrics, and code.
5. **Data Layer & Reliability**:
   - Write declarative schema definitions with foreign keys, composite indexes on queried filters, and automated timestamp triggers.
   - Use connection pooling and prepared statements for serverless database execution.
---
## 5. STEP-BY-STEP SCAFFOLDING ROADMAP
- **Phase 1: Workspace & Root Config**: Initialize package manager, monorepo configuration (`turbo.json`, `tsconfig.base.json`, `package.json`).
- **Phase 2: Database Schema & Client**: Set up the data layer (SQLite, S3): client, connection pool, models, and migration scripts.
- **Phase 3: Design Tokens & UI Primitives**: Build accessible `Button`, `Input`, `Card`, `Badge`, and layout wrappers inside `packages/ui`.
- **Phase 4: Core Application Routes & Handlers**: Implement primary authentication, user session handling, and application routes.
- **Phase 5: Quality Assurance & Build Verification**: Run `tsc --noEmit`, ESLint, Prettier, and smoke test suites to ensure zero compilation or runtime errors.
---
## 6. EXECUTION INSTRUCTIONS
1. Review all specifications, architectural guardrails, and stack choices above.
2. Present the full monorepo directory tree structure.
3. Systematically generate the complete, production-ready codebase according to the 5-phase roadmap above — starting with the root workspace setup, followed by the database schema, UI design system package, and full-stack application routes until the repository is fully scaffolded and ready to run.
Scaffolded something with this prompt?
Would you pick this stack for a embedded backend project?

Frequently asked about PocketBase

What is PocketBase built with?

PocketBase is written in Go, using embedded SQLite via modernc.org/sqlite for persistence, Goja for embedded JavaScript execution, and a Vite-bundled administrative dashboard.

Does PocketBase require CGO to compile?

No. PocketBase uses the pure Go modernc.org/sqlite driver, allowing CGO_ENABLED=0 compilation for static, self-contained binaries on any supported operating system.

How does PocketBase handle real-time data sync?

PocketBase utilizes Server-Sent Events (SSE) implemented in apis/realtime.go, notifying connected clients whenever records are created, updated, or deleted.

Can I extend PocketBase without writing Go code?

Yes. The built-in JS VM plugin runs JavaScript files placed in pb_hooks/, letting users intercept database events and register custom routes using JavaScript.

One email a month: new deep dives and stack trends

New source-audited architectures, head-to-head comparisons and the monthly stack report. No spam, unsubscribe anytime.

use-this-stack.md