1. Web App and API Boundary
The web UI is a React single-page app (apps/web) that uses React Router for
client-side navigation. All data comes from an edge Worker API whose base URL is computed
by helpers in the web app.
A typical browser request follows this path:
- User navigates to a route like
/,/player/:postId, or/settings - The SPA route component uses an API helper to call the Worker API (e.g.,
GET /posts,GET /profile/:handle) - The API Worker reads/writes from D1, R2, Durable Objects, and Analytics Engine
- The route component maps the JSON response into view models and renders the page
Key idea: All data flows through a single API Worker endpoint. The SPA never talks directly to storage services.
2. Feed and Post Flow
The home feed and post views are backed by feed endpoints in the API worker:
- Home feed (
/) usesGET /feed/discover?mode=latest,GET /feed/following, andGET /feed/for-you - Discover (
/discover) usesGET /feed/discoverwith search and tag filters - Post detail (
/post/:id) fetches the post; runnable posts redirect to/player/:id
The SPA uses shared schemas from @vibecodr/shared to validate API responses
before mapping them into feed and player models.
3. Feed Ranking and Personalization
Feed ranking uses linear, non-ML scoring over existing signals to keep behavior auditable while allowing future model swaps without API changes.
Signals Used
- Exponential recency decay
- Engagement rate (likes, comments, saves, runs, completions, remixes, shares)
- Creator/topic affinity
- Mild boosts for runnable vibes and author plan/featured flags
Feed Modes
- Following feed - Recency-weighted with creator and topic affinity inputs
- Discovery feed - Global trending using engagement velocity/acceleration, size penalty for large creators, boost for runnable vibes
- For You feed - Blends following, topic matches, discovery pool, and fresh posts; enforces diversity (no >3 consecutive posts per author)
Safety Filters
Excludes muted/blocked users, quarantined content; applies search/tag filters before scoring; falls back to discover feed if personalization is empty.
4. Vibe Runtime Execution
When a user opens a vibe in the player at /player/:postId, the system loads
and runs that vibe in a sandboxed iframe:
- Player page fetches the post and associated runtime manifest from the Worker API
- Player enforces client-side runtime budgets (max concurrent runners, boot timeouts by surface and plan)
- Player selects an execution origin: prefers
https://c-<capsuleId>-rt.vxbe.space/__vibecodr/frame(optional?artifactId=...) and preview useshttps://<slug>-rt.vxbe.space/__vibecodr/preview; if unavailable, fall back to opaquenullorigin - Runtime HTML and bundle load in a sandboxed iframe with strict CSP. Cross-origin runtimes may use
sandbox="allow-same-origin"because the runtime origin is not onvibecodr.space - The iframe runs user code purely client-side; there is no server-side Node.js runtime
- Iframe and host communicate via
postMessageprotocol carrying params, logs, and telemetry - Logs and runtime events are forwarded to the Worker; runs are finalized via runtime completion APIs
Key idea: Vibes execute entirely in the browser. The iframe is sandboxed and communicates with the host only via postMessage. No server-side Node.js runtime.
Dependency loading is deterministic and recorded in the runtime manifest:
- Dependencies are read from
package.jsonplus lockfiles (package-lock.jsonorpnpm-lock.yaml) - Publish requires exact versions; ranges fail until pinned
- Published artifacts mirror imports at
/deps/:sha256(.js)with immutable caching @handle/slugresolves tohttps://vibecodr.space/lib/@handle/slug?v=VERSION- Draft and legacy artifacts can fall back to
https://esm.sh
Runtime Budgets
- maxConcurrentRunners - Caps how many vibes can run at once
- clientStaticBootMs - How long a vibe has to signal ready before timeout
- webContainerBootHardKillMs - Hard deadline for heavier runtimes
5. Pulse Execution Flow
Pulses are per-user server-side functions deployed on Workers for Platforms. The execution path is implemented in the API Worker and dispatch worker.
- Pulse is created and managed via pulse APIs in
workers/api - Deployment scripts build and deploy a per-pulse Worker using the template in
workers/vibe-template - Manual runs are quota-checked against the user's plan in the API Worker
- Vibes and triggers call
POST /pulses/:id/run(Clerk for private pulses; public/unlisted can be anonymous - no account required) - Dispatch worker validates grant, enforces rate limits and concurrency caps, checks kill switches
- Dispatch routes to the user's pulse Worker in the dispatch namespace
- Pulse Worker returns a Response or JSON result; dispatch attaches metadata headers
Key idea: Browser only talks to API Worker; dispatch uses short-lived grants minted by the API, and grants are only required when you cannot attach Clerk or when calling dispatch directly.
6. Secrets and Proxy Flow
Pulse secrets are stored encrypted in D1 and accessed via a zero-gap protection model.
- User creates secrets via
/me/secrets; secrets are stored encrypted with AES-256-GCM - Secrets can be bound to specific pulses via
/pulses/:id/secrets - Pulse code calls
env.secrets.fetch(url, { secret: "key" })to make authenticated requests - The dispatch worker intercepts these requests, injects the secret value server-side, and returns the response
- Raw secret values are never exposed to user code-only key names via
env.secrets.keys()
SSRF + Infra Blocklist
Dispatch proxy egress (secrets, token, and connections fetch) enforces the Vibecodr infra blocklist, validates per-secret allowlists when configured, blocks private/loopback/metadata IP ranges, and re-checks every redirect hop.
7. Safety, Limits, and Plans
Safety and cost controls are implemented across the API Worker, dispatch worker, and shared config:
- All write endpoints wrapped in auth checks; moderation/admin endpoints enforce role checks
- Public read endpoints are rate-limited via Cloudflare and in-Worker controls
- Expensive operations (imports, publishes, runs, pulse executions) checked against plan-specific quotas before work is performed
- Runtime iframes are sandboxed; origin is either opaque
null(same-origin fallback) or a cross-origin VXBE runtime host (*.vxbe.space) for stronger isolation - Plan limits defined once in
packages/shared/src/plans.tsand consumed by both web app and API Worker
Plan Limits Summary
| Plan | Price | Storage | Bundle | Pulses | Runs/mo |
|---|---|---|---|---|---|
| Free | $0 | 1 GB | 10 MB | 3 | 1,500 |
| Creator | $9/mo | 5 GB | 50 MB | 15 | 150,000 |
| Pro | $39/mo | 25 GB | 100 MB | 50 | 1,000,000 |
See /pricing for current pricing. Limits defined in packages/shared/src/plans.ts.
8. Real-time Streams
Vibecodr provides SSE streams for admin analytics:
- Admin Analytics (
GET /admin/runtime-analytics/stream) - Pushes runtime event deltas and compile latency stats. Admin-only.
Notifications use client-side SWR polling (GET /notifications/unread-count) for cost efficiency.
Streams send heartbeats to keep connections alive; clients back off on 429/5xx and retain REST endpoints as fallback.
9. Key API Endpoints
Anchor endpoints organized by domain:
| Domain | Endpoints | Purpose |
|---|---|---|
| Feed/Read | GET /feed/discover, GET /feed/following, GET /feed/for-you, GET /posts/discover |
Feed modes (latest via mode=latest, discover, following, for-you), search, tags |
| Posts | GET/POST /posts/:id, /like, /comments |
CRUD, social interactions |
| Capsules | GET /capsules/:id, /manifest, /bundle |
Vibe container data, runtime manifest, compiled bundles |
| Pulse CRUD | GET/POST /pulses, PATCH/DELETE /pulses/:id |
Manage server-side functions |
| Pulse Run | POST /pulses/:id/run (public/unlisted), POST /pulse-grants (private/external) |
Execution; grants only when Clerk auth is not available |
| Secrets | GET/POST /me/secrets, GET/POST /pulses/:id/secrets |
Manage encrypted secrets for pulse authentication |
| Connections | GET /me/connections, POST /me/connections/:provider/start, DELETE /me/connections/:provider |
OAuth connections for pulses (tokens never exposed to user code) |
| Webhooks | POST /t/:triggerId |
Inbound webhook entry point for http_webhook triggers |
| Triggers | GET/POST /triggers, PATCH /triggers/:id, POST /triggers/validate-cron |
Automation rules, cron validation, and action management |
| Profiles | GET /users/:handle, GET /profile/:handle |
User profiles, follow relationships |
10. Studio Keyboard Shortcuts
The Studio IDE uses Alt-based keyboard shortcuts to avoid conflicts with browser shortcuts (Ctrl/Cmd). Here's the complete reference:
| Category | Shortcut | Action |
|---|---|---|
| File Operations | Alt+S |
Save current file |
Alt+Enter |
Publish project | |
| Panel Toggles | Alt+E |
Toggle file sidebar |
Alt+P |
Toggle preview panel | |
Alt+B |
Toggle config panel | |
Alt+J |
Toggle console panel | |
Alt+/ |
Toggle hints panel | |
Alt+Shift+M |
Toggle problems panel | |
| Editor | Alt+\ |
Toggle split editor |
| Search | Alt+Shift+F |
Find in files |
Alt+H |
Find and replace | |
| Tab Management | Alt+W |
Close current tab |
Alt+Shift+T |
Reopen closed tab | |
Alt+Left/Right |
Navigate between tabs | |
Alt+1-9 |
Jump to tab by number | |
| Error Navigation | F8 |
Go to next error |
Shift+F8 |
Go to previous error |
Note: All shortcuts use Alt modifier to avoid conflicts with browser shortcuts. Access the full reference in Studio via Help > Keyboard Shortcuts.
11. Image/Asset Support
Agent guidance for assets and images:
- Never suggest local disk paths (C:\... or /Users/...); they do not exist in the browser.
- Use project assets inside the capsule (Studio > Files or Settings > Storage V2).
- HTML/CSS use relative paths; React should import assets.
- Cover/thumbnail uploads accept PNG, JPEG, WebP, and AVIF.
- Avatar uploads accept PNG, JPEG, WebP, and GIF.
- SVG, HTML, and XML are served with CSP script-src 'none' and frame-ancestors 'none'.
<!-- HTML -->
<img src="assets/products/shirt.png" alt="" />
/* CSS */
.hero {
background-image: url("assets/products/shirt.png");
}
// React
import shirtUrl from "./assets/products/shirt.png";
<img src={shirtUrl} alt="" />
12. Architecture Summary
Taken together, these flows describe how a request moves through Vibecodr: from the browser into Workers, through D1/R2/Durable Objects and back, using only the behavior defined in the codebase.
Key idea: Three-layer architecture. Browser SPA handles UI. API Worker handles data and orchestration. Dispatch Worker routes to isolated per-user pulse Workers. Each layer adds security/isolation.