You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
codex-web-local is a lightweight, browser-based web UI for OpenAI Codex. It mirrors the Codex Desktop experience and runs on top of the Codex app-server, allowing remote access to a local Codex instance from any browser.
No Pinia / Vuex: All state lives in a single composable (useDesktopState). Reactive refs + computed properties manage thread, message, model, and UI state.
Realtime transport: Client prefers WebSocket on /codex-api/ws for server-to-client notifications, with automatic fallback to SSE (EventSource) on /codex-api/events. Client-to-server RPC stays on HTTP POST.
Single child process: The Node server spawns exactly one codex app-server child process and multiplexes all RPC calls through it via stdin/stdout.
Shared bridge state: A global singleton (AppServerProcess + MethodCatalog) survives Vite HMR reloads during development.
Rename, reorder, remove projects (persisted to localStorage)
Unread indicators
Track read/unread state per thread
Auto-refresh
Optional 4-second polling with visual countdown
Collapsible sidebar
Resizable (260–620px), toggle with Ctrl/Cmd+B
Scroll state persistence
Remember scroll position per thread across navigation
Password auth
Optional password protection with auto-generated passwords in production
New thread creation
"Let's build" hero view with folder selector
Live overlay
Reasoning text, activity labels, and error messages during agent work
Turn duration display
"Worked for Xm Ys" summary after turn completion
Not Yet Implemented
Based on the app-server protocol (documentation/APP_SERVER_DOCUMENTATION.md), the following capabilities are available in the protocol but not yet surfaced in the UI:
Realtime events arrive via WebSocket on /codex-api/ws (fallback: EventSource on /codex-api/events)
Each event is passed to applyRealtimeUpdates() for immediate UI effects (activity labels, live text, in-progress flags)
Events are also passed to queueEventDrivenSync() which debounces (220ms) a full data refresh
The debounced syncFromNotifications() calls loadThreads() and loadMessages() to reconcile server state
Routing
Route
Path
Behavior
Home
/
New thread creation view with folder selector
Thread
/thread/:threadId
Thread conversation view
Redirect
/new-thread
Redirects to Home
Fallback
/:pathMatch(.*)*
Redirects to Home
Bidirectional sync between selectedThreadId state and URL is handled via Vue watchers in App.vue.
Development
Prerequisites
Node.js >= 18
codex CLI installed and in PATH
Scripts
Command
Description
pnpm run dev
Install deps + start Vite dev server (port 5173)
pnpm run build
Type-check + build frontend + build CLI
pnpm run build:frontend
vue-tsc --noEmit && vite build
pnpm run build:cli
tsup (builds CLI to dist-cli/)
pnpm run preview
Preview production build
Dev Mode
pnpm run dev installs dependencies and starts a Vite dev server that includes the codex bridge as middleware. The bridge spawns codex app-server as a child process. The frontend calls /codex-api/* endpoints on the same origin.
The CLI starts an Express server that serves the built frontend from dist/ and uses the same bridge middleware. Password authentication is enabled by default with an auto-generated password printed to the console.
Auth (Production)
Default: auto-generated password printed to console on startup
Login: POST /auth/login with { password } body
Session: HttpOnly cookie codex_web_local_token
Uses constant-time comparison to prevent timing attacks
Design Principles
Minimal dependencies: Only essential packages — no state management library, no component library, no CSS framework beyond Tailwind
Protocol-first: The UI is designed around the Codex app-server protocol; all features map directly to RPC methods and notifications
Offline-resilient: localStorage persistence ensures the UI recovers gracefully from disconnections
Reference equality optimization: Extensive use of identity checks and shallow merging to minimize unnecessary Vue re-renders
Single composable pattern: All state and logic in one place for discoverability, at the cost of file size (~2000 LOC)