System Overview
Single Application:- SvelteKit frontend + PocketBase backend, all in one binary
- SQLite database stores code and content
- Files (images, uploads) stored in filesystem (or optional S3)
- No microservices, no separate database server
- Minimal operational overhead
- One process to run and monitor
- SQLite file contains code/content, filesystem has assets
- Simple backups (database + storage in
pb_datadirectory) - Easy to reason about and debug
Data Flow
Development Workflow
Publishing Workflow
Key Components
PocketBase
Role: Backend, database, auth, file storage, realtime- SQLite database management
- User authentication and permissions
- File uploads and serving (local filesystem and optinally S3)
- Realtime subscriptions for live updates
- Custom API routes
- Database:
pb_data/data.db - Storage:
pb_data/storage/ - Backups:
pb_data/backups/
PocketBase can be configured to use S3-compatible storage (AWS S3, Cloudflare R2, etc.) instead of local filesystem for uploaded files. This is useful for scaling.
Svelte Compiler
Role: Transforms block code into production JavaScript Where it runs:- In the browser using Web Workers (not server-side)
- Rollup worker for JavaScript bundling
- PostCSS worker for CSS processing
- On publish: Compiles all blocks to static files
- In preview: Compiles blocks for live preview
- Not during content edits (content changes don’t trigger compilation)
- Fetches block HTML/CSS/JS from database
- Injects content variables from fields
- Compiles in browser worker (parallel processing)
- Generates static HTML for each page
CodeMirror
Role: Code editor for developers Features:- Syntax highlighting for HTML, CSS, JavaScript
- Autocompletion for field variables
- Error detection
- Keyboard shortcuts (
Cmd/Ctrl + 1/2/3to switch panes)
TipTap
Role: Rich text editor for content Features:- WYSIWYG editing with formatting toolbar
- Markdown shortcuts
- Paste from Word/Google Docs
- Link editing
File Structure
Database Schema
Key Collections:sites: Site configuration and settingssite_symbols: Block code (HTML, CSS, JS)site_symbol_fields: Field definitions for blockssite_symbol_entries: Field values/contentpage_types: Page type configurationspages: Individual pagespage_sections: Block instances on pagespage_section_entries: Content for block instances
- Blocks (symbols) are reusable across pages
- Content (entries) is separate from code (symbols)
- Pages reference blocks via sections
- Supports multi-locale content (entries have locale field)
How Publishing Works
Static Site Generation
Step 1: Compile blocks- Fetch all blocks used on the site
- Compile each block’s Svelte code
- Generate optimized JavaScript bundles
- Upload bundles
- For each page, fetch content from database
- Inject content into compiled blocks
- Render to static HTML
- Upload pages
- Copy new and updated JavaScript bundles to
_symbols/ - Copy new and updated media files to
_uploads/ - Copy new and updated pages to
[page]/index.html - Clean up unused files
- Static HTML files for every page
- Shared JavaScript bundles
- Fast, CDN-friendly output
- No database queries on page load
Preview vs Published
Preview (in editor):- Compiles blocks on-demand
- Shows unsaved changes
- Uses iframe for isolation
- Hot module replacement for fast updates
- Pre-compiled static files
- No build step on request
- Served directly from file system
- Fast, cacheable responses
Realtime Updates
Pala uses PocketBase’s realtime subscriptions for live collaboration: What syncs in realtime:- Block code/content changes
- Page structure updates
- User activity indicators
- Field value updates
- SSE connection to PocketBase
- Receive updates as they happen
- UI updates automatically
Performance Characteristics
Database:- SQLite is fast for read-heavy workloads
- Single-file makes backups trivial
- No network latency (in-process database)
- Scales to millions of rows
- Compile time grows linearly with page count
- ~3-20 seconds for most sites
- Compilation is parallelized in browser workers
- Limited by user’s browser/device, not server
- Static output is extremely fast to serve
- CodeMirror handles large files well
- Preview compilation is cached
- Realtime updates are throttled
- UI stays responsive during saves
Self-Hosting Considerations
System Requirements:- Docker
- 1GB RAM minimum
- Persistent disk storage
- Compilation happens client-side (no server CPU for builds)
- Server only needs to serve API requests and static files
- Horizontal scaling not needed (static output can be served from CDN)
- Database size grows with content (~1MB per 50 pages)
- Use S3 storage to better integrate with content delivery networks
- SQLite file contains code/content (
pb_data/data.db) - Storage directory contains uploaded files (
pb_data/storage/) - Backup both database + storage directory
- Or create and download backup from PocketBase
- If using S3, you only need to backup the database
Technology Stack Summary
Frontend:- SvelteKit 2
- Svelte 5 (with runes)
- TailwindCSS
- CodeMirror 6
- TipTap 2
- Golang
- PocketBase
- SQLite 3
- Vite