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

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

Prop

Type

Compatibility

MethodStatusNotes
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.
signedUploadUrlThrows — 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.

On this page