In-Dashboard JavaScript Hook Studio & Recipe Marketplace
Pocket Kit provides a dedicated, serverless-style JavaScript Hook Studio directly within your dashboard. It transforms PocketBase from a standalone SQLite database into a complete, extensible backend suite competing with Firebase Functions and Supabase Edge Functions.
โก Core Capabilities
graph TD
A[Dashboard Hook Studio] --> B[1-Click Recipe Marketplace]
A --> C[Interactive Code Editor]
A --> D[Live Event Mocking & Tester]
B -->|Select Template| C
C -->|Dry Run| D
D -->|Zero Errors| E[AST Sandbox & Shadow Boot]
E -->|Atomic Hot-Reload| F[Active Tenant Instance]
1. In-Dashboard Code Editor
Author server-side logic in JavaScript/TypeScript or Go with real-time linting, bracket matching, syntax highlighting, and autocomplete.
- Target Directory:
/tenants/<instance_id>/pb_hooks/*.pb.js - Zero-Downtime Hot Reload: Changes are compiled and hot-reloaded into your isolated PocketBase instance runtime automatically.
- Environment Vault Integration: Access encrypted secrets seamlessly via
$os.getenv("VARIABLE_NAME").
๐งช 2. Live Event Mocking & Dry Run Engine
Before deploying code to production, test and simulate runtime events safely in an isolated sandbox with zero database mutations.
Supported Event Simulators:
- HTTP Route Endpoints (
routerAdd):- Customize HTTP method (
GET,POST,PUT,DELETE), URL path, headers, and request body JSON. - Inspect simulated response status codes, JSON payloads, and execution duration in milliseconds.
- Customize HTTP method (
- Database Create Triggers (
onRecordCreate):- Pass custom record JSON attributes (e.g.
email,role,plan). - Verify field transformations, default values, and pre-insert validations.
- Pass custom record JSON attributes (e.g.
- Database Update & Delete Triggers (
onRecordUpdate/onRecordDelete):- Inspect audit logs, mutation diffs, and outgoing webhook payloads.
๐ 3. 1-Click Recipe Marketplace
Pocket Kit includes a catalog of production-verified, pre-built server hook recipes ready to install with one click:
| Recipe Name | Category | Required Env Keys | Description |
|---|---|---|---|
| Stripe Webhook & Subscription Sync | Payments | STRIPE_WEBHOOK_SECRET, STRIPE_SECRET_KEY | Parses checkout.session.completed and upgrades user records automatically. |
| Discord New User Alerts | Alerts | DISCORD_WEBHOOK_URL | Posts formatted embed alerts to Discord on new signups. |
| Resend Transactional Email | Communication | RESEND_API_KEY, APP_SENDER_EMAIL | Sends branded HTML welcome emails on user creation. |
| Telegram Bot Webhook | Communication | TELEGRAM_BOT_TOKEN | Responds to /start and /stats commands directly from chat. |
| Sliding Window API Rate Limiter | Security | None | In-memory IP throttle limiting callers to 30 req/min. |
| OpenAI / Claude Auto-Summarizer | AI & LLMs | OPENAI_API_KEY | Generates two-sentence summaries for newly inserted articles or posts. |
| Audit Trail & Mutation Logger | Security | None | Records all database mutations with caller IDs and timestamps into audit_logs. |
| Clean URL Slug Generator | Utility | None | Auto-generates URL-friendly slugs from title or name fields. |
๐ป Code Examples
/// <reference path="../pb_data/types.d.ts" />
routerAdd("POST", "/api/stripe/webhook", (e) => { const stripeSecret = $os.getenv("STRIPE_WEBHOOK_SECRET"); const signature = e.request.header.get("stripe-signature");
if (!stripeSecret) { return e.json(500, { error: "STRIPE_WEBHOOK_SECRET missing in Environment Vault" }); }
const rawBody = e.requestInfo().body || {}; if (rawBody.type === "checkout.session.completed") { const session = rawBody.data?.object || {}; const email = session.customer_email || session.customer_details?.email;
if (email) { const user = $app.findAuthRecordByEmail("users", email); user.set("stripe_customer_id", session.customer); user.set("plan", "pro"); $app.save(user); $app.logger().info("[Stripe] User upgraded: " + email); } }
return e.json(200, { received: true });});/// <reference path="../pb_data/types.d.ts" />
onRecordCreate((e) => { e.next();
const webhookUrl = $os.getenv("DISCORD_WEBHOOK_URL"); if (!webhookUrl) return;
$http.send({ url: webhookUrl, method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ embeds: [{ title: "๐ New User Registered!", color: 5793266, fields: [ { name: "ID", value: e.record.id, inline: true }, { name: "Email", value: e.record.getString("email"), inline: true } ] }] }), timeout: 5 });}, "users");/// <reference path="../pb_data/types.d.ts" />
onRecordCreate((e) => { e.next();
const apiKey = $os.getenv("RESEND_API_KEY"); const sender = $os.getenv("APP_SENDER_EMAIL") || "onboarding@yourdomain.com"; const userEmail = e.record.getString("email");
if (!apiKey || !userEmail) return;
$http.send({ url: "https://api.resend.com/emails", method: "POST", headers: { "Authorization": "Bearer " + apiKey, "Content-Type": "application/json" }, body: JSON.stringify({ from: sender, to: [userEmail], subject: "Welcome to our Platform!", html: "<h2>Welcome aboard!</h2><p>Your backend is live and ready.</p>" }), timeout: 8 });}, "users");๐ 4. AST Sandboxing & Security Verification
All hooks authored via the Hook Studio or deployed via Remote MCP pass through a 4-step verification gauntlet:
- AST Static Linting: Disallows unapproved module loaders (
require(), ESimport) and blocks direct host command execution ($os.cmd,$os.exec). - Shadow Boot Test: Evaluates the script in an isolated ephemeral PocketBase child process on a dynamic port to confirm zero startup panics.
- Execution Latency Check: Confirms the hook initializes within standard response thresholds (under 3,000ms).
- Atomic Deployment: Writes to a staging buffer and atomically swaps the
.pb.jsfile to ensure zero partial-write corruption.
๐ Accessing the Hook Studio
- From Instance Cards: Click the โก Actions menu or Code2 icon on any instance to launch the instance-scoped Hook Studio.
- From Sidebar: Navigate to Extensibility โ Server Hooks to access multi-instance hook management, recipe searching, and live event testing.