---
title: PocketBase
description: Comparing TrailBase & PocketBase.
---

import { Aside } from "@astrojs/starlight/components";
import { githubPath } from "@/lib/github";

import GettingTrailBase from "../getting-started/_getting_trailbase.mdx";

Firstly, PocketBase is amazing! It paved the way for single-executable
application bases, is incredibly easy-to-use, and a polished
experience. Gani, the person behind it, is a mad scientist 🙏.

From a distance PocketBase and TrailBase are both single-executables providing
almost identical feature sets: REST APIs, realtime updates, authentication, file
storage, a runtime for custom endpoints, admin dashboard..., all on top of SQLite.

For the sake of this comparison, we'll dive a little deeper to have a closer
look at their differences both technically and philosophically.

## Goals

TrailBase was born out of admiration for PocketBase trying to move the needle
in a few areas:

- Less abstraction and embracing standards (SQL[^1], a full ES6 runtime through WASM,
  JWT, UUID) to not get in your way, avoid lock-in and making it easier to
  adopt TrailBase either fully or as piece-meal as well as getting rid of it if
  necessary.
- Untethered access to SQLite[^2] including features such as recursive CTEs,
  virtual tables and extensions, e.g., providing vector search and geoip out of
  the box[^3], unlocking more use-cases and standard solutions to well-known
  problems.
- Be lightweight and fast to rival in-process SQLite performance at least for
  higher-level languages.
- Be just as easy to self-host with aspirations to be even easier to manage a
  fleet of deployments across integration tests, development, and production.
  We'd also like to eventually tackle replication.
- Be simple, flexible and portable enough to support data analysis use-cases.
  Imagine a self-contained data science project that ships an interactive UI
  with vector search and custom JS extensions alongside its data.

## Differences

Beyond goals and intentions, let's look at some of the more practical differences:

### Language & Performance

PocketBase being written in Go and TrailBase in Rust may be the most instantly
visible difference.
Preference aside, this will likely matter more to folks who want to use
either as a framework rather than the standalone binary or modifying the core.

In practice, both languages are solid, speedy options with rich ecosystems.
Though Rust's lack of a runtime and lower FFI overhead gives it the edge in
terms of performance.
Measuring we found that TrailBase's APIs are roughly [10x faster](/reference/benchmarks/).
This may sound like a lot but is the result of SQLite itself being extremely
fast meaning that even small overheads weigh heavily.

Independently, TrailBase offers a WebAssembly runtime over PocketBase's
JavaScript interpreter.
This allows for strict state isolation between requests and supports a
wide-range of guest languages - currently JS/TS and Rust with more to come.
A custom Rust endpoint can be up to 140x faster than a PocketBase JS one.

### Framework Use

Both PocketBase and TrailBase allow customization using their built-in runtimes.
However, some users may want even more control and built their own binaries
using only bits and pieces.
This is what we refer to as library or framework use. For this use-case
language preference and prior experience of you and your team will likely matter
a lot more with PocketBase written in Go and TrailBase in Rust.

Framework use is something PocketBase has allowed for a long time and is really
great at.
TrailBase technically allows it too, but at this point it really feels more
like an afterthought while we focus on the standalone experience.
Expect TrailBase to improve significantly in this area.

### Features

Looking more closely at the breadth of similar features, varioud differences
emerge.
In lieu of trying to enumerating all of these constantly evolving differences,
let's look a some of the nifty tricks that TrailBase has up its sleeve:

- Support for multiple independent SQLite DBs [^6].
- Language independent bindings via JSON-schema with strict type-safety
  enforced all the way from the client to the database[^4].
- A WASM runtime, supporting multiple guest languages for custom endpoints and
  up to 140x speed-up[^5].
- Untethered access to SQLite with all its features and capabilities.
- First-party client libraries beyond JS/TS and Dart for
  C#, Kotlin, Swift, Go, Python and Rust.
- Ships with a simple pre-built auth UI to get you started. You can always
  graduate to your own. In fact, the first-party one is just a WASM component
  waiting to be forked.
- Support for geospatial data and `GeoJSON` APIs.
- Support for stable more and more efficient cursor-based pagination in addition to `OFFSET`.
- An admin UI that "works" on small mobile screens 😅.

### Contributing & Licensing

Both PocketBase and TrailBase are truly open-source: they accept contributions
and are distributed under [OSI-approved](https://opensource.org/licenses) licenses.
PocketBase is distributed under the permissive MIT license, while TrailBase
uses the OSL-3.0 copyleft license.
We chose this license over more popular, similar copyleft licenses such as
AGPLv3 due to its narrower definition of derivative work that only covers
modifications to TrailBase itself. This is similar to GPL's classpath or LGPL's
linkage exception allowing the use of TrailBase as a framework and JS runtime
without inflicting licensing requirements on your original work.

## Final Words

PocketBase is great and both PocketBase and TrailBase are constantly evolving
making it hard to give clear guidance on which to pick when.
If you can afford the luxury, I'd recommend to give them both a quick spin.
After all they're both incredibly quick and easy to deploy.

In the end, if you're looking for mileage or framework use-cases you're likely
better off with PocketBase.
Otherwise it may be worth giving TrailBase a closer look, especially when
flexibility and performance matter.

<GettingTrailBase />

---

[^1]:
    We believe that SQL a ubiquitous evergreen technology, which in of itself
    is already a high-level abstraction for efficient, unified cross-database
    access.
    ORMs, on the other hand, often look great in examples but many fall apart
    for more complex tasks. They're certainly bespoke, non-transferable
    knowledge, and lead to vendor lock-in.

[^2]:
    Maybe more in line with SupaBase's philosophy. We suspect that PocketBase
    relies on schema metadata by construction requiring alterations to be
    mediated through PocketBase to keep everything in sync.

[^3]:
    All extensions can be built into a small, standalone shared library and
    imported by vanilla SQLite to avoid vendor lock-in.

[^4]:
    Note that SQLite is not strictly typed by default. Instead column types
    merely a type affinity for value conversions.

[^5]:
    Depends a lot on the guest language and the specific taks in question. 140x
    is what we measured in heavy computational tasks comparing Goja with
    Rust->WASM. It's apples to oranges, yet practically applicable.

[^6]:
    This can aid with physical separation and offer a path to overcoming potential locking bottlenecks.
