Outcomes, not just examples.
Pick a path. Each one is an ordered run of 3–5 examples — by the end of the path, you've shipped a concrete outcome, not a stack of unread tabs.
Get Builder running in 5 minutes
From npm-less zero to a working Save round-trip — three steps, ~20 minutes including coffee. By the end you have a live canvas posting JSON + HTML to your own endpoint.
-
BASIC
Quick Start
Boot the engine with the default theme + a
mediaUrl— five lines of init, zero backend. -
BASIC
Hello World
Wire a Save button on top of the boot —
getHtml()+getData()+ a singlealert(), no server yet. -
BACKEND
Save to MySQL
Swap the alert for a real
POST /saveto MySQL — schema, prepared statements, error handling.
Outcome A live Builder canvas posting to your own Save endpoint.
Match the Builder to your app's UI
Eight cookbook chrome variants are pre-built. Pick the one that fits your shell, copy four files, ship. Each cookbook entry is fully self-contained — index.php · style.css · init.js · README.md.
-
COOKBOOK
Minimal — canvas + thin top strip
Smallest footprint — canvas + thin top strip with a Save button. Double-null constructor pattern.
-
COOKBOOK
Compact 3-col — widgets + canvas + settings
Classic 3-column SaaS shell — widgets palette · canvas · settings panel inline. All three sub-systems wired.
-
COOKBOOK
Rich 3-col + header — full SaaS chrome
Add an in-wrapper 48 px header carrying Save · Undo · Redo · Export · Preview buttons. Reactive
mode:changed+history:changeconsumers. -
COOKBOOK
Mobile — tab-based chrome (Widgets / Canvas / Settings)
Tab-based phone chrome — same engine, single-column with
data-mobile-tabdriving slot visibility. WAI-ARIA tablist baked in.
Outcome A chrome variant copy-pasted into your own host page.
Add custom widgets, elements, and controls
The extension surface — ship a new block class with its own Settings panel, register it via the engine API, render it into the canvas. Every step lands a fully-typed extension that survives getData() ↔ load() round-trip.
-
EXTENSIONS
Custom Widget — subclass BaseWidget, register, ship
Subclass
BaseWidget, register viawidgetsBox.addWidget, drop a custom block in the palette. -
EXTENSIONS
Custom Element — extend BaseElement, register, save/load round-trip
Subclass
BaseElement, register viaBuilder.registerElement, ship a custom EJS template +parse()round-trip. -
EXTENSIONS
Custom Control — extend ColorPickerControl with brand swatches, wire via getControls()
Subclass
ColorPickerControl, append brand swatches, wire viagetControls()so the Settings panel renders it. -
EXTENSIONS
i18n Locale Pack — I18n.init() + locale switcher with builder re-render
Add multi-locale messages via
I18n.init()and re-render the canvas + palette on locale switch.
Outcome A custom block class with its own Settings panel rendering inside your Builder.
Multi-tenant + auth + storage — production stack
The full SaaS shape: tenant identity from auth, asset storage on S3, doc state in MySQL, realtime sync on a WebSocket channel, multi-instance isolation by closure-captured tenantId. The engine stays tenant-naive — multi-tenant is a host concern.
-
BACKEND
Save to MySQL
Persist doc JSON + rendered HTML in a real database — one row per page id.
-
BACKEND
Save Assets to S3
Move asset uploads off the local filesystem onto S3 (or MinIO) — signed URLs, scalable storage.
-
BACKEND
Session Auth
Wrap save + asset upload in session auth — only the owner mutates their docs, identity flows through every endpoint.
-
BACKEND
Realtime Sync
Broadcast
document:changedover a WebSocket channel — collab + tab-sync without polling. -
EXTENSIONS
Multi-tenant SaaS — closure-captured tenantId per Builder
Closure-capture
tenantIdper Builder constructor — engine bundle stays tenant-naive, isolation is pure host concern.
Outcome A multi-tenant Builder with auth-protected save, S3 uploads, and per-tenant isolation.