Skip to content
Files SDK
Esc
navigateopen⌘Jpreview
On this page

PocketBase

PocketBase via the official JS SDK. Maps the unified key/blob API onto a dedicated collection with a unique key field and a single-file body field.

Installation

pocketbase is an optional peer dependency of files-sdk - install alongside the SDK so the adapter’s imports resolve at runtime.

npm install files-sdk pocketbase
pnpm add files-sdk pocketbase
yarn add files-sdk pocketbase
bun add files-sdk pocketbase

Usage

PocketBase via the official pocketbase JS SDK. PocketBase has no object-store primitive - files live as field values on records inside collections. The adapter maps the unified key/blob API onto a dedicated collection: each upload becomes (or updates) a record whose configurable key field holds the user-facing string key and whose configurable file field holds the body.

import { Files } from "files-sdk";
import { pocketbase } from "files-sdk/pocketbase";

const files = new Files({
  adapter: pocketbase({
    collection: "files",
    // Auto-loads url + auth from POCKETBASE_URL,
    // POCKETBASE_ADMIN_EMAIL + POCKETBASE_ADMIN_PASSWORD, or
    // POCKETBASE_AUTH_TOKEN. Or pass an existing PocketBase client.
    //
    // Collection must already exist with a unique-indexed text `key`
    // field and a single-value `file` field. Field names are
    // configurable via `keyField` / `fileField`.
  }),
});

Options

PropType
collectionstring

Collection name (or id) that holds the file records. Must already exist with the configured `keyField` (unique-indexed text) and `fileField` (single-value file). The adapter does not create or migrate the collection — set it up via the PocketBase admin UI or migrations first.

Typestring
client?PocketBaseClient

Existing PocketBase client. Highest precedence — when passed, all auth options below are ignored. Useful when the host app already shares one client across auth, realtime, and storage.

TypePocketBaseClient
url?string

PocketBase backend URL (e.g. `https://pb.example.com`). Falls back to `POCKETBASE_URL`.

Typestring
adminEmail?string

Superuser email. Combined with `adminPassword` to auth as a superuser before each session. Falls back to `POCKETBASE_ADMIN_EMAIL`.

Typestring
adminPassword?string

Superuser password. Falls back to `POCKETBASE_ADMIN_PASSWORD`.

Typestring
authToken?string

Pre-issued auth token. Saved into the client's `authStore` directly — use this when you already have a token from elsewhere (e.g. an OAuth2 exchange or a custom user auth flow). Falls back to `POCKETBASE_AUTH_TOKEN`. Mutually exclusive with the admin email/password pair; if both are provided, the explicit token wins.

Typestring
keyField?string

Name of the text field on the collection holding the user-facing key. Must be unique-indexed. Defaults to `"key"`.

Typestring
fileField?string

Name of the single-file field on the collection holding the body. Defaults to `"file"`.

Typestring
publicBaseUrl?string

Origin used to build URLs from `url()`. When set, `url(key)` returns `${publicBaseUrl}/${key}` and skips PocketBase's file URL entirely — appropriate when a CDN sits in front of the PB instance. When unset, `url()` falls back to `pb.files.getURL(record, filename)`.

Typestring

Compatibility

Method Status Notes
upload ⚠️ Stream bodies are buffered up-front - the SDK uploads via multipart FormData with a Blob, which has no streaming form. User metadata and cacheControl throw - PocketBase has no per-file HTTP cache headers and no arbitrary-metadata field on the file; add extra typed columns to the collection and write via raw if you need them. Existing keys are updated in place (no duplicate-key error); new keys create a new record. Resumable uploads (control) are not supported — PocketBase uploads in a single multipart request.
download ⚠️ No streaming primitive - PocketBase’s JS SDK has no binary download API, so the adapter resolves the record, mints a short-lived file token via pb.files.getToken() when authenticated, and fetches the file URL with fetch(). Size and content-type come back from the HTTP response, not the record - PB doesn’t store them on the record itself.
delete
list ⚠️ PocketBase’s stable list API is offset/limit (page/perPage), not cursor-based. The adapter encodes the next page number as a numeric cursor string so the unified API works unchanged. prefix is matched server-side via the ~ operator on the configured keyField. List items expose lazy bodies (one fetch per .text()/.arrayBuffer() call) — PocketBase records don’t carry size or content-type, so list entries return size: 0 and type: 'application/octet-stream' until the body is read.
search ⚠️ Built on listAll — inherits this adapter’s list behavior above. Client-side key match (glob, regex, substring, exact).
head ⚠️ PocketBase records don’t carry size, content-type, or etag for their file fields, so head() returns size: 0 and type: 'application/octet-stream' until the body is read via the lazy body factory. lastModified is sourced from the record’s updated field. The filename PocketBase generated on upload is exposed under metadata.filename.
exists
copy ⚠️ Read-then-write — PocketBase has no server-side copy primitive, so the source record’s file is downloaded and uploaded as a new record under the destination key. Costs an egress + an ingest; not atomic.
url ⚠️ Default returns pb.files.getURL(record, filename) — permanent for public collections, threaded with a short-lived file token from pb.files.getToken() when the client is authenticated. With publicBaseUrl, returns <publicBaseUrl>/<key>. expiresIn is silently ignored — PocketBase fixes the file-token TTL server-side. responseContentDisposition always throws — PB has no per-URL Content-Disposition override; use raw and the ?download=true query string instead.
signedUploadUrl Throws — PocketBase has no presigned upload primitive. Writes always go through the authenticated API; mint a short-lived auth token for the client and call create/update directly, or proxy uploads through your application.

Was this page helpful?