The Problem

Developers need a single‑file‑style backend that supplies realtime SQLite storage, file handling, user management and an admin UI without wiring together a full‑stack framework. Maintaining such a compact stack manually is error‑prone and forces duplicated glue code for authentication, CRUD, and subscriptions.

What This Does

The repository is a portfolio of ten self‑contained projects that together implement the PocketBase platform. Core server logic lives in core/ (e.g., core/base.go, core/collection_model.go), API handlers in apis/ (e.g., apis/record_auth.go), and the admin UI in ui/ (Svelte/Vite). The Go entry points are cmd/serve.go (binary pocketbase serve) and the example app examples/base/main.go.

Key files:

  • pocketbase.go – factory (New, Start) that builds the application object.
  • core/base.go – defines NewBaseApp, the central hub for hooks, logger, and transaction info; called from 91 other files.
  • apis/serve.go – Serve function (line 59) wires HTTP router, middlewares, and realtime hub; reaches 232 functions.
  • ui/vite.config.js & ui/package.json – compile the Svelte admin UI.

How It Is Wired

Execution starts in examples/base/main.go:19 (main). It creates the app with pocketbase.New() (defined in pocketbase.go) and registers a custom route via app.OnServe().BindFunc. The call chain is:

  1. main → pocketbase.New() → core/base.NewBaseApp (via core/base.go).
  2. app.Start() → apis/serve.go:Serve (the server bootstrap).
  3. Serve registers middlewares, the realtime hub, and the CRUD APIs, then calls Run.

Run is the most‑invoked function (303 call sites) and ultimately triggers the HTTP listener.

The internal call graph shows a hub:

  • core/base.go (119 functions, 5 types) is the widest‑impact module – any change here ripples to 91 callers.
  • core/collection_model.go (34 functions, 3 types) creates collections and registers collection‑level hooks, referenced by 79 files.

Filesystem touches are short and explicit:

  • main → MustRegister → Register → registerMigrations → filesContent reads migration files via os.ReadFile.
  • Serve → Close writes a lock file (w.open).

No circular import edges were detected, so the call flow is acyclic. The most‑connected functions (Run, NewTestApp, Cleanup, New, Collection) have the highest blast radius because they are invoked from dozens of test utilities and production code.

How To Use It

# Clone the upstream repository
git clone https://github.com/moses-y/pocketbase
cd pocketbase

# Build the Go binary (example app)
go build ./examples/base

# Run the server (default port 8090)
./base serve

The UI can be rebuilt with the bundled npm toolchain:

cd ui
npm ci          # reads ui/package-lock.json
npm run dev     # starts Vite dev server (defined in ui/package.json)

Configuration – the server reads environment variables from ui/.env (currently committed, see health notes). No other mandatory config files are required for a basic run.

Real‑World Use

A typical microservice might embed PocketBase to provide a lightweight data store with realtime push to a web client:

app := pocketbase.New()
app.OnServe().BindFunc(func(se *core.ServeEvent) error {
    se.Router.GET("/metrics", func(re *core.RequestEvent) error {
        return re.JSON(200, map[string]any{"uptime": time.Since(start)})
    })
    return se.Next()
})
log.Fatal(app.Start())

The admin UI (ui/dist) can be served from the same binary, giving internal users a ready‑made dashboard.

Code Health & Issues

Measured findings (static analysis):

  • HIGH – Deep nesting (51 locations, e.g., apis/realtime.go).
  • HIGH – Duplicated code blocks (≈1 100 repeats across 258 files).
  • HIGH – Oversized test files (up to 1 532 lines).

Code‑health audit:

  • HIGH – GitHub Actions pinned to tags (.github/workflows/release.yaml).
  • HIGH – Committed .env files (ui/.env, ui/.env.development).
  • MEDIUM – No explicit permissions for GITHUB_TOKEN.
  • MEDIUM – No Dependabot or Renovate config.
  • MEDIUM – No dependency‑vulnerability scan in CI.
  • MEDIUM – No pre‑commit secret gate.
  • LOW – Missing job timeout-minutes.
  • LOW – Missing repository convention files (.editorconfig, formatter config).

All issues are reported directly from the analysis; recommended fixes are outlined in the audit.

The Bottom Line

PocketBase delivers a compact, Go‑native backend with realtime SQLite and a built‑in admin UI, suitable for small‑to‑medium services that value a single‑binary deployment. The codebase is functional but suffers from high cognitive load (deep nesting, duplication) and several security‑hygiene gaps (committed env, unpinned CI actions). Teams comfortable with Go and willing to invest in refactoring and hardening can adopt it; otherwise consider a more actively maintained fork or upstream version.