Ultimate Pb Framework
Enterprise-grade skill for javascript, usage, pocketbase, client. Includes structured workflows, validation checks, and reusable patterns for pocketbase.
Ultimate PB Framework
A comprehensive skill for building full-stack applications with PocketBase — covering project setup, collection design, API integration, authentication flows, real-time subscriptions, file handling, and production deployment as a complete backend solution.
When to Use This Skill
Choose Ultimate PB Framework when you need to:
- Build a complete backend using PocketBase as a single binary
- Set up authentication with email, OAuth2, and custom providers
- Implement real-time features with PocketBase subscriptions
- Design a full-stack application with PocketBase as the API layer
- Understand PocketBase's capabilities and limitations holistically
Consider alternatives when:
- You need high-concurrency write workloads (consider PostgreSQL)
- You need complex SQL joins or stored procedures (use a relational DB)
- You need microservices architecture (PocketBase is monolithic by design)
Quick Start
# Download and run PocketBase wget https://github.com/pocketbase/pocketbase/releases/download/v0.23.0/pocketbase_0.23.0_linux_amd64.zip unzip pocketbase_0.23.0_linux_amd64.zip ./pocketbase serve # Admin UI: http://127.0.0.1:8090/_/ # API: http://127.0.0.1:8090/api/
// Frontend SDK setup import PocketBase from "pocketbase"; const pb = new PocketBase("http://127.0.0.1:8090"); // Authentication await pb.collection("users").authWithPassword("[email protected]", "password123"); console.log(pb.authStore.isValid); // true console.log(pb.authStore.model.id); // user record ID // CRUD operations // Create const post = await pb.collection("posts").create({ title: "Hello World", content: "My first post", author: pb.authStore.model.id, status: "published", }); // Read const posts = await pb.collection("posts").getList(1, 20, { filter: 'status = "published"', sort: "-created", expand: "author", }); // Update await pb.collection("posts").update(post.id, { title: "Updated Title", }); // Delete await pb.collection("posts").delete(post.id);
Core Concepts
PocketBase Architecture
| Component | Purpose | Technology |
|---|---|---|
| HTTP Server | REST API + Admin UI | Go net/http |
| Database | Data storage and querying | SQLite (embedded) |
| File Storage | User uploads and attachments | Local filesystem / S3 |
| Auth System | User management and authentication | Built-in + OAuth2 |
| Realtime | Live data subscriptions | Server-Sent Events |
| Hooks | Server-side business logic | goja (JavaScript) |
Authentication Patterns
// Email/password auth await pb.collection("users").authWithPassword(email, password); // OAuth2 (Google, GitHub, etc.) await pb.collection("users").authWithOAuth2({ provider: "google" }); // Registration const user = await pb.collection("users").create({ email: "[email protected]", password: "securepass123", passwordConfirm: "securepass123", name: "New User", }); // Auth state management pb.authStore.onChange(function(token, model) { console.log("Auth changed:", model?.email); }); // Token refresh await pb.collection("users").authRefresh(); // Logout pb.authStore.clear();
Real-Time Subscriptions
// Subscribe to collection changes pb.collection("posts").subscribe("*", function(e) { console.log(e.action); // "create", "update", "delete" console.log(e.record); // The affected record }); // Subscribe to specific record pb.collection("posts").subscribe(recordId, function(e) { console.log("Record updated:", e.record); }); // Unsubscribe pb.collection("posts").unsubscribe("*"); pb.collection("posts").unsubscribe(recordId); // Use in React import { useEffect, useState } from "react"; function usePBSubscription(collection, filter) { var _a = useState([]), records = _a[0], setRecords = _a[1]; useEffect(function() { // Initial fetch pb.collection(collection).getFullList({ filter: filter }) .then(setRecords); // Subscribe to changes pb.collection(collection).subscribe("*", function(e) { setRecords(function(prev) { if (e.action === "create") return prev.concat([e.record]); if (e.action === "update") return prev.map(function(r) { return r.id === e.record.id ? e.record : r; }); if (e.action === "delete") return prev.filter(function(r) { return r.id !== e.record.id; }); return prev; }); }); return function() { pb.collection(collection).unsubscribe("*"); }; }, [collection, filter]); return records; }
Configuration
| Parameter | Description | Example |
|---|---|---|
pb_url | PocketBase server URL | "http://127.0.0.1:8090" |
data_dir | Data directory | "./pb_data" |
migrations_dir | Migrations directory | "./pb_migrations" |
hooks_dir | Hooks directory | "./pb_hooks" |
s3_storage | Use S3 for file storage | true (production) |
smtp | Email sending configuration | SMTP server settings |
Best Practices
-
Use PocketBase for projects with < 10,000 concurrent users — PocketBase uses SQLite, which handles one writer at a time. It's excellent for most applications but not designed for write-heavy workloads with thousands of concurrent writes per second.
-
Enable S3 storage for production file uploads — Local filesystem storage doesn't scale across multiple servers or survive server replacements. Configure S3-compatible storage (AWS S3, Backblaze B2, MinIO) for production file handling.
-
Use
expandparameter to reduce API calls — Instead of fetching a post and then fetching its author separately, useexpand: "author"to include the related record in a single request. This reduces network round-trips significantly. -
Implement client-side auth state persistence — PocketBase's JS SDK stores auth tokens in memory by default. For SPAs, use
pb.authStore.exportToCookie()or localStorage to persist auth state across page reloads. -
Back up the SQLite database before every deployment — PocketBase stores everything in a single SQLite file. Before deploying schema changes or updates, copy
pb_data/data.dbto a backup location. A corrupted database means total data loss without backups.
Common Issues
Real-time subscriptions disconnect on mobile networks — Mobile networks frequently drop WebSocket/SSE connections. Implement reconnection logic in your client: detect disconnection, wait briefly, then re-subscribe. The PocketBase JS SDK handles basic reconnection but you may need additional logic for state synchronization after reconnect.
File upload fails with no clear error — Common causes: file exceeds collection's maxSize, file MIME type not in mimeTypes whitelist, or reverse proxy client_max_body_size is too small. Check all three when debugging upload failures.
Auth tokens expire and API calls fail silently — The default auth token lifetime is 14 days. Implement pb.collection("users").authRefresh() before critical API calls, or set up an auth refresh interceptor that automatically refreshes expired tokens.
Reviews
No reviews yet. Be the first to review this template!
Similar Templates
Full-Stack Code Reviewer
Comprehensive code review skill that checks for security vulnerabilities, performance issues, accessibility, and best practices across frontend and backend code.
Test Suite Generator
Generates comprehensive test suites with unit tests, integration tests, and edge cases. Supports Jest, Vitest, Pytest, and Go testing.
Pro Architecture Workspace
Battle-tested skill for architectural, decision, making, framework. Includes structured workflows, validation checks, and reusable patterns for development.