← All articles
BACKEND PocketBase: A Complete Backend in a Single Binary 2026-03-08 · 4 min read · pocketbase · backend · sqlite

PocketBase: A Complete Backend in a Single Binary

Backend 2026-03-08 · 4 min read pocketbase backend sqlite authentication api

PocketBase is an open-source backend that ships as a single executable. You download one file, run it, and get a SQLite database, user authentication, file storage, real-time subscriptions, and an auto-generated REST API — all with an admin dashboard. No Docker, no database server, no configuration files.

It fills a gap between "I'll just use a JSON file" and "I need to set up PostgreSQL, Redis, an auth provider, and an object store." For prototypes, internal tools, small SaaS products, and side projects, PocketBase eliminates the entire backend setup phase.

Getting Started

Download the binary for your platform from the PocketBase website, then run it:

./pocketbase serve

That's it. The admin UI is at http://127.0.0.1:8090/_/ and the API is live at http://127.0.0.1:8090/api/. On first launch, you'll create an admin account through the UI.

Collections Are Your Database Tables

PocketBase organizes data into collections, which map to SQLite tables. You create them through the admin UI or via the API. There are three types:

Each collection automatically gets id, created, and updated fields. You add your own fields through the UI: text, number, bool, email, URL, date, file, relation, select, and JSON.

Once a collection exists, PocketBase generates full CRUD endpoints:

# List records
curl http://127.0.0.1:8090/api/collections/posts/records

# Create a record
curl -X POST http://127.0.0.1:8090/api/collections/posts/records \
  -H "Content-Type: application/json" \
  -d '{"title": "Hello", "body": "First post", "published": true}'

# Filter records
curl "http://127.0.0.1:8090/api/collections/posts/records?filter=(published=true)&sort=-created"

The filter syntax supports comparison operators, logical operators, and nested field access. It's not SQL — it's a simpler query language that PocketBase translates to SQL internally.

Authentication Out of the Box

Create an auth collection (the default users collection works), and you get registration, login, password reset, email verification, and OAuth2 — all handled by PocketBase:

# Register
curl -X POST http://127.0.0.1:8090/api/collections/users/records \
  -H "Content-Type: application/json" \
  -d '{"email": "[email protected]", "password": "securepass123", "passwordConfirm": "securepass123"}'

# Login
curl -X POST http://127.0.0.1:8090/api/collections/users/auth-with-password \
  -H "Content-Type: application/json" \
  -d '{"identity": "[email protected]", "password": "securepass123"}'

The login response includes a JWT token. Use it in subsequent requests via the Authorization header. OAuth2 providers (Google, GitHub, Discord, and others) are configured through the admin UI with just a client ID and secret.

Access Rules

Every collection has configurable access rules for list, view, create, update, and delete operations. Rules are expressions that evaluate against the current request:

This replaces the middleware chain you'd typically write in Express or Fastify. Rules are set per-collection in the admin UI and stored in the database, so they're portable with your data.

File Storage

File fields on collections handle uploads automatically. PocketBase stores files on the local filesystem by default, with S3-compatible storage as an option. Files are served through the API with built-in thumbnail generation for images:

# Upload a file
curl -X POST http://127.0.0.1:8090/api/collections/posts/records \
  -F "title=Photo post" \
  -F "[email protected]"

# Access the file (with optional thumb parameter)
# http://127.0.0.1:8090/api/files/posts/RECORD_ID/photo.jpg?thumb=100x100

Real-Time Subscriptions

PocketBase supports real-time updates via Server-Sent Events. Subscribe to changes on any collection:

import PocketBase from "pocketbase";

const pb = new PocketBase("http://127.0.0.1:8090");

pb.collection("posts").subscribe("*", (e) => {
  console.log(e.action); // 'create', 'update', or 'delete'
  console.log(e.record);
});

Subscriptions respect access rules — users only receive events for records they have permission to view.

Extending with Go or JavaScript

PocketBase can be used as a Go framework. Import it as a module and add custom routes, hooks, and middleware:

package main

import (
    "github.com/pocketbase/pocketbase"
    "github.com/pocketbase/pocketbase/core"
)

func main() {
    app := pocketbase.New()

    app.OnServe().BindFunc(func(se *core.ServeEvent) error {
        se.Router.GET("/api/custom", func(e *core.RequestEvent) error {
            return e.JSON(200, map[string]string{"message": "custom endpoint"})
        })
        return se.Next()
    })

    app.Start()
}

For simpler customizations, PocketBase also supports JavaScript hooks (using the Goja runtime) that you can place in a pb_hooks directory — no Go compilation needed.

When PocketBase Fits

PocketBase works well for:

When to Look Elsewhere

PocketBase is backed by SQLite, which means:

Deployment

Deployment is straightforward — copy the binary and your pb_data directory to a server:

# On your server
./pocketbase serve --http="0.0.0.0:8090"

Put it behind Caddy or nginx for TLS termination. Back up the SQLite database with sqlite3 pb_data/data.db ".backup backup.db" or use Litestream for continuous replication to S3.

For production, run it as a systemd service:

[Unit]
Description=PocketBase
After=network.target

[Service]
Type=simple
ExecStart=/opt/pocketbase/pocketbase serve --http="0.0.0.0:8090"
WorkingDirectory=/opt/pocketbase
Restart=on-failure

[Install]
WantedBy=multi-user.target

The Trade-Off

PocketBase trades flexibility for speed of development. You won't build the next Stripe on it, but you can have a working backend with auth, data, files, and real-time updates running in under a minute. For the vast majority of projects that never need to scale beyond a single server, that trade-off is overwhelmingly worth it.

The source is on GitHub, the community is active, and the project is under steady development. If you've been putting off a project because "setting up the backend" felt like too much work, PocketBase removes that excuse entirely.