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

Chat components (Chat/)

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:

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

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

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.