PocketBun Differences From PocketBase

This page tracks user-relevant differences between PocketBase and PocketBun.

Notation used in examples:

Quick links:

PocketBase To PocketBun Migration Checklist

Use this as a quick migration recipe for an existing PocketBase project.

  1. Switch executable and update flow.
    • Replace pocketbase commands with pocketbun.
    • There is no PocketBase-style binary self-update command; update via package manager.
  2. Create (or convert to) a Bun project.
    • Option A: convert your existing project directory:
      • initialize package metadata: bun init
      • add PocketBun dependency: bun add pocketbun
    • Option B: scaffold a new PocketBun project and copy your existing data/code:
      • create project: bun create pocketbun my-app
      • copy your PocketBase pb_* directories into the new project (pb_data, pb_hooks, pb_migrations, optional pb_public)
  3. Keep the project layout, but verify startup working directory.
    • Keep pb_data, pb_hooks, pb_migrations, and optional pb_public.
    • PocketBun resolves default paths from current working directory (CWD), so start from your project root or pass explicit dirs.
  4. Move hooks as-is, then fix hook-chain calls.
    • In handlers that call e.next(), return/await it:
      • sync: return e.next()
      • async: const err = await e.next(); if (err) return err; ...
    • This is especially important for onBootstrap when using async startup paths.
    • If you see OnBootstrap hook didn't fail but the app is still not bootstrapped, this is usually the cause.
    • In .pb.ts hooks, use standard import for neighboring files and dependencies when needed.
  5. Keep API clients and route assumptions.
    • Existing client SDK usage should continue to work with the same API base paths (/api/, /_/).
  6. If you embed PocketBun programmatically, prefer JSVM-compatible naming.
    • Prefer RegisterJSVM* / MustRegisterJSVM* for naming parity with PocketBase JSVM docs.
    • RegisterHooksPlugin* / MustRegisterHooksPlugin* remain aliases.
  7. Run a migration smoke test before deploying.
    • Start: pocketbun serve --dev
    • Verify health: GET /api/health
    • Verify custom hooks/routes and auth flows you use in production.
  8. Review the sections below for details.
    • Use this checklist for the quick pass, then check each section in this page only where your app uses that feature.

Runtime And Distribution

PocketBase:

PocketBun:

CLI Defaults And Paths

PocketBase defaults are resolved relative to executable location. PocketBun resolves defaults from current working directory.

Default paths in PocketBun CLI:

This prevents accidental writes into node_modules-adjacent paths when used as package dependency.

Hooks Plugin Naming

PocketBase JS extension naming uses jsvm package naming. PocketBun keeps those names as primary and also provides aliases:

Both names map to the same plugin registration behavior.

Hooks API And Module Loading

PocketBun supports JSVM-style lowercase naming and keeps Go-style aliases where applicable:

For pb_hooks module loading:

For code-first BaseApp usage:

Async API Extensions

PocketBun keeps sync-compatible APIs but adds async alternatives for I/O-heavy paths.

Area PocketBase-compatible sync API PocketBun async extension
Archive helpers Create, Extract CreateAsync, ExtractAsync
App bootstrap/serve app.bootstrap(), serve(...) app.bootstrapAsync(), serveAsync(...)
Migration helper migrate(...) migrateAsync(...)
Hooks plugin register RegisterJSVM(...) RegisterJSVMAsync(...)
Filesystem factories NewFilesystem() NewFilesystemAsync()
JSVM helpers $http.send(...), $os.readFile(...) $http.sendAsync(...), $os.readFileAsync(...)

Operational Differences

Activity logs

PocketBun persists activity logs through a background worker to reduce main-thread blocking.

Thumbnails

PocketBun uses Sharp for image resizing. Output bytes may differ from PocketBase Go image stack.

Templates

PocketBun $template helper supports common PocketBase template patterns.

For closer Go text/template parity, install optional go-text-template.

JSVM RequestEvent request/response surface

For custom routes, e below means the route event parameter passed to routerAdd(..., (e) => { ... }).

PocketBun now supports the common PocketBase custom-route access patterns:

Remaining incompatibilities in this area:

SQL placeholders and dbx rewriting

PocketBun supports dbx-style query marker rewriting for SQLite helpers. Logged placeholder formats can differ while query behavior remains compatible.

Dev SQL logging format

In --dev mode, PocketBun prints SQL logs using a Bun-native format based on the executed rewritten SQL ([X.XXms] <sql>). The exact formatting may differ from PocketBase and is informational only.

Windows behavior

PocketBase Docs Topics That Do Not Apply Directly

These upstream topics are either intentionally excluded or need reinterpretation for PocketBun:

These are not bugs in PocketBun docs; they are product-level differences.

Intentional Omissions

Intentionally not provided in PocketBun:

Deferred until demand: