U

Ultimate Pb Framework

Enterprise-grade skill for javascript, usage, pocketbase, client. Includes structured workflows, validation checks, and reusable patterns for pocketbase.

SkillClipticspocketbasev1.0.0MIT
0 views0 copies

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

ComponentPurposeTechnology
HTTP ServerREST API + Admin UIGo net/http
DatabaseData storage and queryingSQLite (embedded)
File StorageUser uploads and attachmentsLocal filesystem / S3
Auth SystemUser management and authenticationBuilt-in + OAuth2
RealtimeLive data subscriptionsServer-Sent Events
HooksServer-side business logicgoja (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

ParameterDescriptionExample
pb_urlPocketBase server URL"http://127.0.0.1:8090"
data_dirData directory"./pb_data"
migrations_dirMigrations directory"./pb_migrations"
hooks_dirHooks directory"./pb_hooks"
s3_storageUse S3 for file storagetrue (production)
smtpEmail sending configurationSMTP server settings

Best Practices

  1. 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.

  2. 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.

  3. Use expand parameter to reduce API calls — Instead of fetching a post and then fetching its author separately, use expand: "author" to include the related record in a single request. This reduces network round-trips significantly.

  4. 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.

  5. 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.db to 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.

Community

Reviews

Write a review

No reviews yet. Be the first to review this template!

Similar Templates