Skip to main content
This page goes beyond the high-level architecture diagram and into the specific design decisions, class structures, and data flows that make Vibra Code work. It is intended for contributors who want to understand the codebase deeply before making changes.

Native iOS chat system

The chat UI in Vibra Code is not a React Native component. It is a fully native iOS interface built with Texture (AsyncDisplayKit) and IGListKit, rendering off the main thread at a consistent 60fps regardless of how many messages are in the session. The entire system lives in apps/expo-go/ios/Client/Menu/. The coordinator for the experience is a singleton called EXPreviewZoomManager.

Core files

FilePurpose
EXPreviewZoomManager.h/mMain singleton — coordinates zoom, chat, bars, and the entire preview experience
EXPreviewZoomManager+Zoom.mZoom in/out animations (3D transform with perspective)
EXPreviewZoomManager+ChatView.mChat UI, message rendering, session loading from Convex
EXPreviewZoomManager+TopBar.mTop bar — app name, refresh button, chevron, three-dots menu
EXPreviewZoomManager+BottomBar.mBottom bar — text input, send, mic (voice), image attach, model selector
EXPreviewZoomManager+Keyboard.mKeyboard show/hide handling and layout constraints
EXPreviewZoomManager+Gestures.mTap gestures for zoom/chat toggle
EXPreviewZoomManager+WebPreview.mWeb project preview (WKWebView for non-mobile projects)

Chat components (Chat/)

FilePurpose
EXChatListAdapter.h/mIGListKit + Texture adapter — O(N) diffing for efficient list updates
EXChatMessageNode.h/mASCellNode for user/assistant text messages with markdown
EXChatGroupNode.h/mASCellNode for tool operations — file reads (blue), edits (orange), bash (green)
EXChatTaskCardNode.h/mASCellNode for todo task cards with Liquid Glass effect
EXChatStatusNode.h/m”Working…” status indicator with shimmer animation
EXChatMessageCache.h/mMessage caching for offline support
EXLottieAnimationHelper.swiftCell animations (springIn, fadeIn, shimmer, glass effects)
EXMarkdownHelper.swiftMarkdown parsing (bold, italic, code blocks, links)

Message types

Messages from Convex carry a role and optional tool fields. The chat renderer selects a node type based on which field is populated:
Message typeNode classVisual style
message (user/assistant text)EXChatMessageNodePlain text with markdown rendering
read (file read operation)EXChatGroupNodeBlue accent
edit (file edit operation)EXChatGroupNodeOrange accent
bash (terminal command)EXChatGroupNodeGreen accent
tasks (todo list)EXChatTaskCardNodeLiquid Glass card
status (working indicator)EXChatStatusNodeShimmer animation

Animation system

EXLottieAnimationHelper.swift provides three helpers used across cell nodes:
  • EXCellAnimationHelper — cell appear animations: springIn, fadeIn, slideUp, scaleIn
  • EXTextShimmerHelper — text shimmer effect used on the “Working…” status node
  • EXGlassEffectHelper — iOS 26 Liquid Glass materials with a pre-iOS 26 fallback
All animations use UIView.animate(springDuration:) rather than CAAnimation directly, keeping them compatible with iOS 26+ spring curves.

Services

FilePurpose
EXChatBackendService.h/mAPI calls to the Convex backend — send messages, load sessions
EXAudioRecorderService.h/mVoice recording via AVFoundation
EXAssemblyAIService.h/mSends recorded audio to AssemblyAI for transcription
EXWebPreviewView.h/mWKWebView wrapper for web project previews

Convex schema design

All persistent state in Vibra Code lives in Convex (vibracode-backend/convex/schema.ts). The schema is shared between the backend and the mobile app via a symlink, so both sides always use the same type definitions.

Table overview

TablePurpose
usersOne row per Clerk user. Stores profile, subscription plan, billing mode (tokens vs. credits), credit balances, and push notification tokens.
sessionsOne row per build session. Tracks the sandbox ID, tunnel URL, template, current status, message count, and total cost.
messagesOne row per chat message. Supports text content plus structured fields for every tool the AI agent can use: edits, bash, read, todos, webSearch, mcpTool, codebaseSearch, grep, searchReplace. Also stores images, audio, and video attachments.
paymentTransactionsAudit log of every Stripe and RevenueCat transaction: payments, refunds, chargebacks, plan changes.
globalConfigKey-value pairs for admin-controlled settings (e.g., global agentType override).
convexProjectCredentialsStores Convex OAuth tokens for users who connect their own Convex project.
githubCredentialsGitHub OAuth access tokens per user, used by the push-to-GitHub feature.
revenuecatCredentialsRevenueCat OAuth tokens for the RevenueCat MCP integration.
generatedImagesRecords of every AI-generated or user-uploaded image in the Image Studio.
generatedAudiosRecords of every AI-generated audio file in the Audio Studio.
generatedVideosRecords of every AI-generated video file in the Video Studio.
stolenAppsResearch data from the App Stealer feature — scraped app metadata used to seed AI generation.

Session status state machine

A session moves through a defined sequence of statuses as the sandbox is provisioned and the agent runs. The mobile app displays a human-readable label for each status.
1

IN_PROGRESS

Session record created in Convex. Inngest job queued.
2

CLONING_REPO

E2B sandbox created. The template repository is being cloned.
3

INSTALLING_DEPENDENCIES

Package manager running (e.g., npm install). Maps to startCommands entries with status: "INSTALLING_DEPENDENCIES".
4

STARTING_DEV_SERVER

Dev server starting. Maps to startCommands entries with status: "STARTING_DEV_SERVER".
5

CREATING_TUNNEL

E2B tunnel being established to expose the dev server URL to the phone.
6

RUNNING

Tunnel is live. tunnelUrl is set on the session. The phone can now open the preview.
7

CUSTOM (AI working)

AI agent is actively generating code. The status message is set to whatever the agent reports.
Additional statuses exist for the GitHub push flow: CREATING_GITHUB_REPO, SETTING_UP_SANDBOX, INITIALIZING_GIT, ADDING_FILES, COMMITTING_CHANGES, PUSHING_TO_GITHUB, PUSH_COMPLETE, and PUSH_FAILED.

Inngest background jobs

Inngest handles all long-running work that cannot block an API request. The functions live in vibracode-backend/lib/inngest/functions/.

create-session.ts

Triggered when a user starts a new build. Responsibilities:
  1. Create the E2B sandbox using the template’s image ID (or the default image)
  2. Clone the template repository into the sandbox
  3. Run each startCommand in order, updating the session status as each completes
  4. Create the E2B tunnel and write the tunnelUrl to the Convex session record
  5. Trigger the run-agent function

run-agent.ts

Runs the AI agent inside the sandbox. Responsibilities:
  1. Load the system prompt for the template (resolving FILE: references if needed)
  2. Build the message history from the Convex messages table
  3. Start the configured agent (claude, cursor, or gemini) with the system prompt and message history
  4. Stream tool use events (file reads, edits, bash commands, todo updates) to Convex in real time
  5. Track token usage and compute cost, writing costUSD to each message and totalCostUSD to the session
  6. Set session status back to RUNNING when the agent finishes

push-to-github.ts

Triggered when a user taps the publish button. Responsibilities:
  1. Retrieve the user’s GitHub OAuth token from githubCredentials
  2. Create a new repository on the user’s GitHub account (or reuse an existing one)
  3. Inside the sandbox: initialize git, add all files, commit, and push
  4. Update the session with githubRepository, githubRepositoryUrl, and githubPushStatus

E2B sandbox lifecycle

Each build session gets a dedicated, isolated E2B cloud sandbox. The sandbox is ephemeral — it exists only for the duration of the session.
1

Create sandbox

The create-session Inngest function calls the E2B API to create a new sandbox from the template’s image ID. If no image is specified, E2B uses its default base image.
2

Clone template repository

The sandbox runs git clone <repository> to fetch the starter project from GitHub. The session status is set to CLONING_REPO.
3

Install dependencies

Each startCommand with status: "INSTALLING_DEPENDENCIES" runs in sequence (blocking). The session status updates to INSTALLING_DEPENDENCIES while these run.
4

Start dev server

Each startCommand with status: "STARTING_DEV_SERVER" and background: true launches the dev server as a background process. The session status updates to STARTING_DEV_SERVER.
5

Create tunnel

E2B creates a public HTTPS tunnel to the dev server port (3000). The tunnelUrl is written to the Convex session record. The session status becomes CREATING_TUNNEL then RUNNING.
6

Run AI agent

The run-agent Inngest function starts the AI agent inside the sandbox. The agent reads and edits files, runs bash commands, and streams updates to Convex. Session status is set to CUSTOM with the agent’s current task as the status message.
7

Auto-pause

After a configurable period of inactivity (default: 10 minutes, controlled by AUTO_PAUSE_TIMEOUT_MS), the sandbox is automatically paused by E2B to save credits. A paused sandbox can be resumed on the next message.
The AUTO_PAUSE_TIMEOUT_MS environment variable defaults to 600000 (10 minutes). Lower it to reduce E2B costs on idle sessions; raise it if your users frequently return to sessions after long pauses.

Build docs developers (and LLMs) love