Writes PocketBase server-side JavaScript in the Goja JSVM: pb_hooks, routerAdd, record hooks, cron jobs, and synchronous $app APIs. Use for *.pb.js files, pb_hooks, pb_migrations JS, or server-side PocketBase extensions — not the npm JS SDK. Read quirks.md for Goja gotchas (toString, json fields, hoisting, BadRequestError). Always check target PocketBase version: v0.22 and v0.23+ use different JSVM APIs and docs. PocketBase watches pb_hooks JS on disk and hot-reloads hooks inside the running process without exiting.
Installation
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Writes PocketBase server-side JavaScript in the Goja JSVM: pb_hooks, routerAdd, record hooks, cron jobs, and synchronous $app APIs. Use for *.pb.js files, pb_hooks, pb_migrations JS, or server-side PocketBase extensions — not the npm JS SDK. Read quirks.md for Goja gotchas (toString, json fields, hoisting, BadRequestError). Always check target PocketBase version: v0.22 and v0.23+ use different JSVM APIs and docs. PocketBase watches pb_hooks JS on disk and hot-reloads hooks inside the running process without exiting.
PocketBase JSVM
PocketBase embeds a Goja JavaScript engine for server-side extensions. Code runs inside the PocketBase process — synchronous, no Node/Browser APIs.
Version split — read this first
v0.23 is a breaking JSVM boundary. PocketHost runs both legacy (≤ v0.22) and modern (≥ v0.23) instances. Always confirm the instance PocketBase version before writing or porting hooks — do not mix APIs across versions.
When in doubt, open the JSVM reference for that version — hook names, route handler signatures, and $app methods differ. For mothership v0.39 port work, read v023-upgrade.md and the official JSVM upgrade guide.
Pre-flight checklist
Before writing hook code, verify:
Target PocketBase version — use the matching JSVM docs (≤ v0.22 vs ≥ v0.23)
No async/await, Promises, or .then()
No fetch, setTimeout, setInterval, DOM APIs
No Node built-ins (fs, http, path, etc.)
Use require() for modules (CommonJS only)
Use $app / record APIs — not new PocketBase()
External HTTP via $http.send() (sync), not fetch
$app.store() values that cross requests: JSON.stringify/parse at boundaries — never mutate get() results in place (app-store.md)
Json fields, hook routers, client errors: skim quirks.md if behavior looks like Node
For full environment constraints, see constraints.md. Goja behavioral quirks (toString, hoisting, json fields, error sanitization): quirks.md.
PocketBase watches hook JS on disk (pb_hooks/*.pb.js and files loaded via require()). When they change, it reloads hook code inside the running process — the PocketBase process does not exit. This is separate from PM2 or Docker restarts.
Operational implications:
Do not git checkout, rsync, or deploy while PocketBase is running if the operation swaps hook files incrementally. A mid-checkout tree can be picked up and loaded as a torn mix of old and new code.
Mothership: stop before branch switches or bulk hook deploys (e.g. v39.sh --forward keeps mothership stopped until checkout finishes, then pm2 reload).
Customer instances on PocketHost: FTP/phio deploy restarts the instance container so hooks reload from a consistent tree — different mechanism, same “don’t run torn hooks” goal.
Hook categories
Names differ by version — check the JSVM reference for your target.
Request body (≥ v0.23) — use e.bindBody() + DynamicModel, not JSON.parse(readerToString(e.request.body)):
let data = newDynamicModel({ trusted_ips: [] })
e.bindBody(data)
data = JSON.parse(JSON.stringify(data)) // required before destructuring / $common validatorsconst { trusted_ips } = data
Quick reads: e.requestInfo().body. Raw stream: readerToString(e.request.body) only for webhooks / signature verification.
Concurrent hooks must not share live Goja objects via $app.store(). Use JSON string boundaries and setFunc for atomic read-modify-write. See app-store.md.
Examples
See hooks-examples.md for copy-paste patterns from this repo and PocketHost docs.
API reference
Pick the JSVM reference for the target version (see Version split above).