greendesertsnow/pocketbase-skillsMIT78 files

Pocketbase Best Practices

PocketBase development best practices covering collection design, API rules, authentication, SDK usage, query optimization, realtime subscriptions, file handling, deployment, and server-side extending (Go + JSVM). Current as of PocketBase v0.40 and JS SDK v0.28. Use when building PocketBase backends, designing schemas, implementing access control, setting up auth flows, or optimizing performance.

Specification
Skill ID
greendesertsnow/pocketbase-skills/pocketbase-best-practices
Publisher
greendesertsnow
Repository
pocketbase-skills
Installs
0
Files
78
License
MIT
Requires
Works with any agent. Covers PocketBase v0.36+, current as of v0.40; JS SDK v0.28.
Synced
Sep 23, 2026
How to use it

Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.

greendesertsnow/pocketbase-skills/pocketbase-best-practicesInstalls these files
  • AGENTS.md
  • SKILL.md
  • metadata.json
  • references/api-rules-security.md
  • references/authentication.md
  • references/collection-design.md
  • references/file-handling.md
  • references/production-deployment.md
  • references/query-performance.md
  • references/realtime.md
  • references/sdk-usage.md
  • references/server-side-extending.md
  • rules/_sections.md
  • rules/_template.md
  • rules/auth-impersonation.md
  • rules/auth-mfa.md
  • rules/auth-oauth2.md
  • rules/auth-otp.md
  • rules/auth-password.md
  • rules/auth-token-management.md
  • rules/coll-auth-vs-base.md
  • rules/coll-field-types.md
  • rules/coll-geopoint.md
  • rules/coll-indexes.md
  • rules/coll-relations.md
  • rules/coll-view-collections.md
  • rules/deploy-backup.md
  • rules/deploy-configuration.md
  • rules/deploy-rate-limiting.md
  • rules/deploy-reverse-proxy.md
  • rules/deploy-scaling.md
  • rules/deploy-sqlite-considerations.md
  • rules/deploy-superuser-ips.md
  • rules/ext-compose-request-flow.md
  • rules/ext-cron-jobs.md
  • rules/ext-filesystem.md
  • rules/ext-filter-binding-server.md
  • rules/ext-go-custom-sqlite.md
  • rules/ext-go-migrations.md
  • rules/ext-go-setup.md
  • rules/ext-hooks-chain.md
  • rules/ext-hooks-record-vs-request.md
  • rules/ext-js-migrations.md
  • rules/ext-js-setup.md
  • rules/ext-jsvm-modules.md
  • rules/ext-jsvm-scope.md
  • rules/ext-mailer.md
  • rules/ext-routing-custom.md
  • rules/ext-settings.md
  • rules/ext-testing.md
  • rules/ext-transactions.md
  • rules/file-serving.md
  • rules/file-upload.md
  • rules/file-validation.md
  • rules/query-back-relations.md
  • rules/query-batch-operations.md
  • rules/query-expand.md
  • rules/query-field-selection.md
  • rules/query-first-item.md
  • rules/query-n-plus-one.md
  • rules/query-pagination.md
  • rules/realtime-auth.md
  • rules/realtime-events.md
  • rules/realtime-reconnection.md
  • rules/realtime-subscribe.md
  • rules/rules-basics.md
  • rules/rules-cross-collection.md
  • rules/rules-filter-syntax.md
  • rules/rules-locked-vs-open.md
  • rules/rules-request-context.md
  • rules/rules-strftime.md
  • rules/sdk-auth-store.md
  • rules/sdk-auto-cancellation.md
  • rules/sdk-error-handling.md
  • rules/sdk-field-modifiers.md
  • rules/sdk-filter-binding.md
  • rules/sdk-initialization.md
  • rules/sdk-send-hooks.md

What this skill tells the agent

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

CategoryImpactWhat it protects you from
Collection DesignCriticalWrong field types, missing indexes, manual ID strings instead of relations
API Rules & SecurityCriticalData leaks from empty/incorrect access rules, filter injection
AuthenticationCriticalBroken password/OAuth2/OTP/MFA flows, token mishandling
SDK UsageHighBad client setup, swallowed errors, cancelled-request bugs
Query PerformanceHighN+1 queries, over-fetching, missing pagination
RealtimeMediumDropped subscriptions, unauthenticated realtime access
File HandlingMediumUnvalidated uploads, wrong file URLs, missing thumbnails
Production & DeploymentMediumNo backups, no rate limits, exposed superuser access
Server-Side ExtendingHighGo/JSVM hook mistakes, transaction misuse, unsafe filter binding

Quick Reference

Collection Design (CRITICAL)

  • 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

SDK Usage (HIGH)

  • sdk-initialization: Initialize client once, reuse instance
  • sdk-auth-store: Use AsyncAuthStore for React Native/SSR
  • sdk-error-handling: Catch ClientResponseError, check status codes
  • sdk-auto-cancellation: Disable auto-cancel for concurrent requests
  • sdk-filter-binding: Use filter binding to prevent injection

Query Performance (HIGH)

  • query-expand: Expand relations to avoid N+1 queries
  • query-field-selection: Select only needed fields
  • query-pagination: Use cursor pagination for large datasets
  • query-batch-operations: Batch creates/updates when possible

Realtime (MEDIUM)

  • realtime-subscribe: Subscribe to specific records or collections
  • realtime-events: Handle create, update, delete events separately
  • 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 pb_hooks/; add /// <reference path="../pb_data/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: pb_migrations/<unix>_*.js with migrate(upFn, downFn); auto-discovered by filename
  • ext-mailer: Resolve sender from app.Settings().Meta at send-time; never ship no-reply@example.com; create the mail client per send
  • ext-settings: Read via app.Settings() at call time; set PB_ENCRYPTION (32 chars) to encrypt _params at rest
  • ext-testing: tests.NewTestApp(testDataDir) + tests.ApiScenario; defer app.Cleanup(), assert ExpectedEvents
  • ext-compose-request-flow: Composite walkthrough showing which app instance is active at each layer (route → tx → hook → enrich)
  • ext-go-custom-sqlite: Only use DBConnect when you need FTS5/ICU; DBConnect is called twice (data.db + auxiliary.db)
  • ext-jsvm-scope: Variables outside handlers are undefined at runtime — load shared config via require() inside the handler
  • ext-jsvm-modules: Only CJS (require()) works in goja; bundle ESM first; avoid mutable module state

Example Prompts

Try these with your AI agent to see the skill in action:

Building a new feature:

  • "Design a PocketBase schema for an e-commerce app with products, orders, and reviews"
  • "Implement OAuth2 login with Google and GitHub for my app"
  • "Build a real-time notification system with PocketBase subscriptions"
  • "Create a file upload form with image validation and thumbnail previews"

Fixing issues:

Use this skill in a project

Open any RiverX project, search the Skills panel for greendesertsnow/pocketbase-skills/pocketbase-best-practices, and install it in one click.

Use this skill