Webview Server Evaluation
June 29, 2026 ยท View on GitHub
Context
The current launcher starts the bundled launcher/webview-server.py helper
with python3 "$SCRIPT_DIR/.codex-linux/webview-server.py" "$CODEX_LINUX_WEBVIEW_PORT" --bind 127.0.0.1 for the extracted webview
bundle. It waits for the configured port to become reachable before launching
Electron, validates the served origin, and exports ELECTRON_RENDERER_URL so
side-by-side app IDs can use an isolated local origin.
The extracted webview payload is a static bundle under codex-app/content/webview and is relatively large: about 35 MB across 693 files. The generated index.html references hashed assets through relative paths, so the app still expects a stable local origin.
Options
1. Keep the bundled Python server
What changes:
- Keep
launcher/webview-server.pyas the webview static-file server - Keep lifecycle, readiness, adoption, and port-collision handling in the launcher
- Keep explicit no-store/no-cache response headers in the helper
Benefits:
- Lowest implementation risk
- No new runtime-binary build or packaging step
- Preserves the existing static-asset serving model
Risks:
- Python remains an external runtime dependency for the launcher path
- Startup reliability still depends on a separate process being spawned correctly
- Performance improvements are limited, because the helper still uses Python's standard HTTP server stack
2. Ship a tiny Rust static-file server
What changes:
- Replace the Python server with a small Rust binary that serves
content/webview - Bundle that binary with the Linux app or package it alongside the launcher
- Add deterministic startup, port selection, and readiness signaling
Benefits:
- Better control over startup behavior, logging, and shutdown
- Fewer runtime dependencies once the Rust binary is packaged
- More room for future optimizations around caching and path handling
Risks:
- Larger implementation and maintenance surface
- Requires packaging updates and a new build artifact
- Could duplicate functionality that the current app may only need in a very narrow way
3. Remove the local server entirely
What changes:
- Change the Electron/webview integration so the app can load the static bundle directly
- Eliminate the localhost origin requirement
Benefits:
- Simplest runtime model if it is truly feasible
- Removes a whole local-server process from the launcher path
- Best theoretical startup behavior
Risks:
- Highest product risk
- May require app-bundle changes outside this Linux repo
- Relative asset loading and origin-sensitive behavior could break in subtle ways
Recommendation
Keep the bundled Python helper for now. Revisit a Rust helper only if startup or lifecycle evidence shows Python remains a bottleneck after the current readiness, ownership, and cache-header handling.
Why this wins:
- The historical problem looked more like process orchestration than raw server throughput, and that now lives in launcher-side ownership/readiness logic.
- The webview payload is static, so the launcher only needs a reliable local origin, not a high-performance application server.
- This path preserves compatibility while leaving the door open for a Rust server later if evidence shows Python is still a bottleneck.
Integration Points
If we later replace the bundled Python helper with a Rust server, the change points are:
install.shstaging for the webview helper- the launcher startup block around the configured webview port
- packaging if a Rust server binary is added
- launcher logging, ownership, adoption, and cleanup logic around the PID file and helper shutdown
Risks To Watch
- Port conflicts on the configured webview port
- Stale launcher/server processes after crashes
- Chromium waiting on a server that has not finished binding yet
- Hidden assumptions in the extracted app about a localhost origin
Acceptance Criteria For A Future Change
- Electron starts reliably when the launcher is invoked once
- A stale server process does not block a new launch
- The webview origin is available before Electron tries to load it
- Launcher logs clearly show server start, bind, and shutdown events
- The app still renders the same webview assets without broken relative paths
Future Test Plan
- Launcher smoke test for start/stop/restart behavior
- Port-collision test for the configured webview port
- Stale-process cleanup test
- Basic render test that verifies the webview assets are reachable from the expected origin