Files included with this skill beyond the listing page.
skill mdSKILL.md10,967 B
docsSUMMARY.md432 B
History
First seen on skills.sh
First recorded snapshot · 705 installs
SKILL.md
PocketBase Best Practices
PocketBase is a single-binary backend (SQLite + REST + realtime + auth) that is easy to start with and easy to misuse at scale. This skill gives AI agents the guardrails: 64 rules across 9 categories, each with an incorrect vs. correct code example, covering the mistakes agents actually make — insecure API rules, unindexed queries, broken auth flows, N+1 expands, leaked server-side handles.
Updated for PocketBase v0.40 and JS SDK v0.28 (August 2026). Works with v0.36+.
How rules are prioritized
Every rule carries an impact level: Critical = security holes or broken data models, High = performance and correctness problems, Medium/Low = operational polish. When rules conflict, higher impact wins.
What's covered
Category
Impact
What it protects you from
Collection Design
Critical
Wrong field types, missing indexes, manual ID strings instead of relations
API Rules & Security
Critical
Data leaks from empty/incorrect access rules, filter injection
coll-field-types: Use appropriate field types (json for objects, select for enums)
coll-auth-vs-base: Extend auth collection for users, base for non-auth data
coll-relations: Use relation fields, not manual ID strings
coll-indexes: Create indexes on frequently filtered/sorted fields
coll-view-collections: Use views for complex aggregations
coll-geopoint: Store coordinates as json field with lat/lng
API Rules (CRITICAL)
rules-basics: Always set API rules; empty = public access
rules-filter-syntax: Use @request.auth, @collection, @now in rules
rules-request-context: Access request data via @request.body, @request.query; @request.context values: default/oauth2/otp/password/realtime/protectedFile
rules-cross-collection: Use @collection.name.field for cross-collection checks
rules-locked-vs-open: Start locked, open selectively
rules-strftime: Use strftime('%Y-%m-%d', created) for date arithmetic (v0.36+)
Authentication (CRITICAL)
auth-password: Use authWithPassword for email/password login
auth-oauth2: Configure OAuth2 providers via Admin UI; run ≥v0.38.2 (pre-linking hijack fix); provider logos come inline from listAuthMethods() (v0.37+)
auth-otp: Two-step requestOTP → authWithOTP; rate-limit requestOTP and never leak email existence
auth-token-management: Store tokens securely, refresh before expiry
auth-mfa: Enable MFA for sensitive applications
auth-impersonation: Use impersonation for admin actions on behalf of users
realtime-auth: Realtime respects API rules automatically; auth unsets on password change; ~30min absolute connection cap (v0.38+)
realtime-reconnection: Implement reconnection logic — periodic reconnects are by design, re-sync state instead of fighting them
File Handling (MEDIUM)
file-upload: Use FormData for uploads, set proper content types
file-serving: Use pb.files.getURL() for file URLs
file-validation: Validate file types and sizes server-side
Deployment (MEDIUM)
deploy-backup: Schedule regular backups of pb_data
deploy-configuration: Use environment variables for config; mind v0.40 log caps (Log.Data ~16KB) and treat the SQL console (v0.39+) as debug-only
deploy-reverse-proxy: Put behind nginx/caddy in production
deploy-sqlite-considerations: Optimize SQLite for production workloads
deploy-rate-limiting: Enable the built-in rate limiter (fixed-window as of v0.36.7); front with Nginx/Caddy for defense in depth
deploy-scaling: Raise ulimit -n for realtime, set GOMEMLIMIT, enable settings encryption
deploy-superuser-ips: Whitelist superuser access by IP/CIDR in production (v0.38+); recovery via the superuser ips console command
Server-Side Extending (HIGH)
ext-go-setup: Use app.OnServe() to register routes; use e.App inside hooks, not the parent-scope app; v0.40 needs Go 1.27 (encoding/json/v2 — test before shipping)
ext-js-setup: Drop *.pb.js in pbhooks/; add /// <reference path="../pbdata/types.d.ts" />
ext-hooks-chain: Always call e.Next()/e.next(); use Bind with an Id for later Unbind
ext-hooks-record-vs-request: Use OnRecordEnrich to shape responses (incl. realtime); OnRecordRequest for HTTP-only
ext-routing-custom: Namespace routes under /api/{yourapp}/; attach RequireAuth() middleware
ext-transactions: Use the scoped txApp inside RunInTransaction; never capture the outer app
ext-filter-binding-server: Bind user input with {:name} + dbx.Params in FindFirstRecordByFilter / FindRecordsByFilter
ext-filesystem: defer fs.Close() on every NewFilesystem() / NewBackupsFilesystem() handle
ext-cron-jobs: Register with app.Cron().MustAdd(id, expr, fn) / cronAdd(); stable ids, no pb* prefix
ext-go-migrations: Versioned .go files under migrations/; Automigrate: osutils.IsProbablyGoRun()
ext-js-migrations: pbmigrations/<unix>*.js with migrate(upFn, downFn); auto-discovered by filename
ext-mailer: Resolve sender from app.Settings().Meta at send-time; never ship [email protected]; create the mail client per send
ext-settings: Read via app.Settings() at call time; set PBENCRYPTION (32 chars) to encrypt params at rest