pocketbase-best-practices — Claude Code skill: PocketBase rules
A skill with 64 PocketBase rules covering collections, API rules, auth, queries and deployment. Useful when an agent writes your backend and gets access control wrong.
npx skills add greendesertsnow/pocketbase-skills --skill pocketbase-best-practices -a claude-codeWhat pocketbase-best-practices does
The skill hands the agent rules across nine categories: collection design, API rules and security, authentication, SDK usage, query performance, realtime, file handling, production deployment, and server-side extending in Go and JSVM. Every rule carries an impact level from Critical down to Low, with a wrong and a right code example side by side. When two rules conflict, the higher impact wins.
Coverage targets PocketBase v0.36 and up, current as of v0.40 and JS SDK v0.28. It names the mistakes agents actually make: empty API rules that leak data, unindexed queries, N+1 expands, broken login flows, leaked server-side handles. One rule is version-specific — OAuth2 needs v0.38.2 or later, since earlier builds had a pre-linking hijack bug. Worth checking your version if provider login is already live.
Installation runs through npx skills add with the target agent, and the skill file lands in that platform's directory. It works with any agent, but the paths and install commands differ between Claude, Codex, Cursor, GitHub Copilot, Gemini CLI and OpenCode.
What it helps with
- set API rules so records stop leaking to the public
- pick proper field types and relations instead of manual ID strings
- kill N+1 queries with expand and field selection
- wire up password, OAuth2, OTP and MFA login without holes
- get a backend ready for production: backups, rate limits, superuser access
Example prompts for the agent
- Review my PocketBase API rules using the pocketbase-best-practices skill
- Design collections for tasks and comments following pocketbase-best-practices
- Why am I getting N+1 on expand? Walk through it with pocketbase-best-practices
How to install pocketbase-best-practices
1Skills CLI (Vercel)
npx skills add greendesertsnow/pocketbase-skills --skill pocketbase-best-practices -a claude-code2Manually: put the files in place
~/.claude/skills/pocketbase-best-practices/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/pocketbase-best-practices/
1Skills CLI (Vercel)
npx skills add greendesertsnow/pocketbase-skills --skill pocketbase-best-practices -a codex2Manually: put the files in place
.agents/skills/pocketbase-best-practices/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add greendesertsnow/pocketbase-skills --skill pocketbase-best-practices -a cursor2Manually: put the files in place
.cursor/skills/pocketbase-best-practices/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install greendesertsnow/pocketbase-skills pocketbase-best-practices2Manually: put the files in place
.github/skills/pocketbase-best-practices/SKILL.md1Skills CLI (Vercel)
npx skills add greendesertsnow/pocketbase-skills --skill pocketbase-best-practices -a gemini-cli2Platform CLI
gemini skills install https://github.com/greendesertsnow/pocketbase-skills --path skills/pocketbase-best-practicesManually: put the files in place
.devin/skills/pocketbase-best-practices/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add greendesertsnow/pocketbase-skills --skill pocketbase-best-practices -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about pocketbase-best-practices
How do I install pocketbase-best-practices in Claude?
Run npx skills add greendesertsnow/pocketbase-skills --skill pocketbase-best-practices -a claude-code. The skill ends up at ~/.claude/skills/pocketbase-best-practices/SKILL.md.
What does pocketbase-best-practices do?
It gives the agent 64 rules for PocketBase work: collections, API rules, authentication, SDK, queries, realtime, files, deployment and server-side extending. Each rule ships with a wrong and a right code example.
Which PocketBase versions does it cover?
It works with PocketBase v0.36 and newer, current as of v0.40 and JS SDK v0.28. OAuth2 requires v0.38.2 or later.
Source text
SKILL.md · MIT
---
name: pocketbase-best-practices
description: 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.
license: MIT
compatibility: Works with any agent. Covers PocketBase v0.36+, current as of v0.40; JS SDK v0.28.
metadata:
author: community
version: "1.4.0"
repository: https://github.com/greendesertsnow/pocketbase-skills
documentation: https://pocketbase.io/docs/
---
# 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 |
| Authentication | Critical | Broken password/OAuth2/OTP/MFA flows, token mishandling |
| SDK Usage | High | Bad client setup, swallowed errors, cancelled-request bugs |
| Query Performance | High | N+1 queries, over-fetching, missing pagination |
| Realtime | Medium | Dropped subscriptions, unauthenticated realtime access |
| File Handling | Medium | Unvalidated uploads, wrong file URLs, missing thumbnails |
| Production & Deployment | Medium | No backups, no rate limits, exposed superuser access |
| Server-Side Extending | High | Go/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 `[email protected]`; 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:**
- "My list query is slow on 100k records -- optimize it"
- "I'm getting 403 errors on my batch operations"
- "Fix the N+1 query problem in my posts list that loads author data in a loop"
- "My realtime subscriptions stop working after a few minutes"
**Security review:**
- "Review my API rules -- users should only access their own data"
- "Set up proper access control: admins manage all content, users edit only their own"
- "Are my authentication cookies configured securely for SSR?"
- "Audit my collection rules for IDOR vulnerabilities"
**Going to production:**
- "Configure Nginx with HTTPS, rate limiting, and security headers for PocketBase"
- "Set up automated backups for my PocketBase database"
- "Optimize SQLite settings for a production workload with ~500 concurrent users"
- "Deploy PocketBase with Docker Compose and Caddy"
**Extending PocketBase:**
- "Add a custom Go route that sends a Slack notification after a record is created"
- "Write a pb_hooks script that validates an email domain before user signup"
- "Set up FTS5 full-text search with a custom SQLite driver in my Go app"
- "Share a config object across multiple pb_hooks files without race conditions"
## Detailed Rules
Load the relevant category for complete rule documentation with code examples:
- [Collection Design](references/collection-design.md) - Schema patterns, field types, relations, indexes
- [API Rules & Security](references/api-rules-security.md) - Access control, filter expressions, security patterns
- [Authentication](references/authentication.md) - Password auth, OAuth2, MFA, token management
- [SDK Usage](references/sdk-usage.md) - Client initialization, auth stores, error handling, hooks
- [Query Performance](references/query-performance.md) - Pagination, expansion, batch operations, N+1 prevention
- [Realtime](references/realtime.md) - SSE subscriptions, event handling, reconnection
- [File Handling](references/file-handling.md) - Uploads, serving, validation
- [Production & Deployment](references/production-deployment.md) - Backup, configuration, reverse proxy, SQLite optimization
- [Server-Side Extending](references/server-side-extending.md) - Go/JSVM setup, event hooks, custom routes, modules, custom SQLite
© community · MIT · greendesertsnow/pocketbase-skills