Skip to main content
Understanding Pala’s architecture helps with self-hosting, troubleshooting, and contributing to the project.

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
What This Means:
  • One process to run and monitor
  • SQLite file contains code/content, filesystem has assets
  • Simple backups (database + storage in pb_data directory)
  • 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
Files:
  • 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
When it runs:
  • 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)
Process:
  1. Fetches block HTML/CSS/JS from database
  2. Injects content variables from fields
  3. Compiles in browser worker (parallel processing)
  4. Generates static HTML for each page
Browser-based compilation means no server CPU usage during builds. All compilation happens client-side, making the server lightweight and scalable.

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/3 to 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

pb_data/
├── data.db                     # SQLite database (code, content, config)
├── storage/
│   ├── sites/
│   │   └── [hostname]/         # Published static sites
│   │       ├── index.html      # Home page
│   │       ├── _symbols/       # Compiled JavaScript bundles
│   │       ├── _uploads/       # Media files
│   │       └── [page]/         # Individual page HTML files
│   └── _pbc_xxxxxxxxxx/        # Uploaded files managed per collection
└── backups/                    # Backups

Database Schema

Key Collections:
  • sites: Site configuration and settings
  • site_symbols: Block code (HTML, CSS, JS)
  • site_symbol_fields: Field definitions for blocks
  • site_symbol_entries: Field values/content
  • page_types: Page type configurations
  • pages: Individual pages
  • page_sections: Block instances on pages
  • page_section_entries: Content for block instances
Why This Structure:
  • 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
Step 2: Generate pages
  • For each page, fetch content from database
  • Inject content into compiled blocks
  • Render to static HTML
  • Upload pages
Step 3: Update static site
  • 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
Result:
  • 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
Published (live site):
  • 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
How it works:
  • 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
Publishing:
  • 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
Editor:
  • 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
Scaling:
  • 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
Backups:
  • 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
Backend:
  • Golang
  • PocketBase
  • SQLite 3
Build Tools:
  • Vite

Next Steps