# PocketBun

[![CI](https://github.com/pekeler/pocketbun/actions/workflows/ci.yml/badge.svg)](https://github.com/pekeler/pocketbun/actions/workflows/ci.yml)
[![Latest release](https://img.shields.io/github/v/release/pekeler/pocketbun?display_name=tag&sort=semver&color=brightgreen)](https://github.com/pekeler/pocketbun/releases/latest)

PocketBun is a port of [PocketBase](https://pocketbase.io) to TypeScript/Bun.

> PocketBase is an open source Go backend that includes:
> 
> - embedded database (_SQLite_) with **realtime subscriptions**
> - built-in **files and users management**
> - convenient **Admin dashboard UI**
> - and simple **REST-ish API**
>
> PocketBase © 2022–present Gani Georgiev.

## Why?

PocketBase is a well-designed, self-hosted Backend-as-a-Service. You can extend it with Go and JavaScript, but the embedded JS engine has limited ES6/Node compatibility, making customizations difficult.

PocketBun is a semi-automated port that aims for maximum compatibility with PocketBase’s API and behavior while taking full advantage of everything that [Bun has to offer](https://bun.com). It's a version of PocketBase that feels native to JS/TS developers.

## Warning

PocketBase is still under active development and NOT recommended for production. Naturally, the same applies to PocketBun.

## Docs

[PocketBun docs](https://pekeler.github.io/pocketbun/)

## Installation

`bun add pocketbun` to add to an existing project, or `bun create pocketbun my-app` to create a new project.

PocketBun requires Bun `v1.3.12` or newer.

## Quick Start

Create a small server script (for example `server.ts`):

```ts
import { BaseApp, serveAsync } from "pocketbun";

const app = new BaseApp({ dataDir: "pb_data" });
await serveAsync(app, { httpAddr: "127.0.0.1:8090" });
```

Run it:

```sh
bun run server.ts
```

Then visit `http://127.0.0.1:8090/_/` for the Admin UI and `http://127.0.0.1:8090/api/health` for a basic API response.

## Examples

- `examples/simple` — minimal server start
- `examples/advanced` — hooks, migrations, auth, CRUD, files, realtime, and custom routes

## Performance

PocketBun aims to stay in the same performance range as PocketBase. Exact comparisons are noisy because Go (`1.26.0`) and Bun (`1.3.10`) are different runtimes.

Benchmark setup:

- host: Hetzner CCX13 (2 dedicated vCPU, 8 GB RAM)
- versions: PocketBase `v0.36.5`, PocketBun `0.36.5-pocketbun.2`
- method: 5 full runs per system, then mean values per scenario

Results (PocketBun relative to PocketBase):

- scenario range: **6.1x faster to 3.0x slower**
- geometric mean: **1.6x faster**
- aggregate mean benchmark time (sum of mean `Completed` across scenarios): **10m 2s** vs **21m 41s**

In this benchmark batch, PocketBun was generally faster on read-heavy/filter-heavy workloads, slower on create-heavy write workloads, and mostly in the same range elsewhere.

The benchmark suite itself has [known fluctuations](https://github.com/pocketbase/benchmarks/issues/8), so treat these numbers as directional rather than absolute.

Memory footprint and file transfer behavior:

- Idle memory: PocketBun uses about `100 MiB` more baseline RSS than PocketBase.
- API load: typical API traffic is in the same range as PocketBase, and PocketBun can use less memory under load.
- Uploads: large file uploads stay in the same ballpark as PocketBase for memory use and throughput.
- Downloads: large local-file downloads stay essentially flat in memory and perform in the same ballpark as PocketBase, including under concurrent load.

Exact numbers vary by OS, runtime, and workload.

## Tests

PocketBun keeps upstream test coverage close to PocketBase and adds around 20% additional PocketBun-specific tests.

Only 2 tests didn't get ported. They are for PocketBase’s self-update command/plugin which doesn't exist in PocketBun.

All tests are passing.

## Differences

All differences to PocketBase are documented [here](https://pekeler.github.io/pocketbun/differences.html), including:

- runtime/distribution differences
- CLI defaults/path resolution differences
- async API extensions
- operational differences (thumbnails, logs, templates, SQL helpers)
- intentionally unsupported upstream topics

## Development Setup

If you want to contribute after cloning from GitHub:

```sh
bun install
bun run upstream:sync
bun run format:fix
bun test --concurrent
bun run typecheck
bun run lint
```

Optional quick smoke test:

```sh
cd examples/simple
bun install
bun run start
```

---
![Jeans with logos.](docs/jeans.webp)
