Skip to content

Run the web-only fork on Bun for macOS and Linux #12

Description

@Igloczek

Problem Statement

iglo.code is becoming a web-only coding-agent client backed by an environment server. Desktop app code is assumed to have already been removed, and the native mobile client is already out of the fork's scope. The maintainer targets macOS and Linux and does not need Windows support.

The fork still inherits Node-oriented startup, helper launchers, executable packaging, and release/update machinery. Upstream's historical reasons for selecting Node included Windows development, reusing Electron's runtime, and consolidating standalone CLI distribution. Those choices do not establish that the remaining web/server application needs Node or that Node performs better for this workload.

The maintainer wants Bun to run the fork's server and first-party JavaScript helpers without maintaining parallel Node and Bun runtime implementations, losing existing web features, or silently downloading an upstream Node-based release during installation or update.

Solution

Make Bun the single supported application runtime for the web-only fork on macOS and Linux. Support both source execution and installed CLI/service execution. Preserve the web client's current behavior and the environment server's ownership of provider processes, terminals, Git, project files, scheduled work, Browser sessions, and Device tools.

Migrate through the existing runtime and adapter boundaries. Keep compatible Node API implementations and libraries when they work under Bun; introduce Bun-specific replacements only for demonstrated incompatibilities or a measured reason. Replace Node SEA packaging and first-party Node launch assumptions. Point release discovery, installation, and updates at iglo-tech/iglo.code.

The application must not require a separate Node installation for its own server, helper scripts, or Device tool bootstrap. A compiled CLI archive must carry any runtime needed for those helpers. Third-party provider CLIs can retain their own documented prerequisites; the migration must distinguish those from requirements imposed by iglo.code.

User Stories

  1. As the fork maintainer, I want one supported application runtime, Bun, so that I can simplify the web-only fork without maintaining a dual-runtime compatibility matrix.
  2. As a contributor, I want the server development commands to launch Bun, so that I exercise the same runtime used by installed environments.
  3. As a contributor, I want the existing Vite+/pnpm workflow to remain usable, so that changing the application runtime does not force an unrelated toolchain migration.
  4. As a macOS user, I want to run the web client against a Bun-hosted environment, so that I can use the fork without an Electron installation.
  5. As a Linux user, I want to run the same supported server and CLI behavior, so that Linux is a first-class deployment target.
  6. As a user running from source, I want to start the application with Bun and an isolated T3 home, so that I do not need Node to run the environment server.
  7. As an installed CLI user, I want the release archive to start outside a repository without a system Node installation, so that installation is self-contained.
  8. As a user, I want existing projects, threads, settings, credentials, and checkpoints to survive the runtime migration, so that changing runtime does not reset my environment.
  9. As a user, I want committed commands, events, projections, and outbox effects to retain their current behavior, so that restarting the server preserves durable work correctly.
  10. As a local web client user, I want the server to serve the client and authenticated APIs correctly, so that the application remains straightforward to start and use.
  11. As a remote web client user, I want pairing, authentication, reconnect, and subscriptions to work over direct access, Tailscale, and supported relay/tunnel connections, so that changing runtime does not limit where I can work.
  12. As a user connected to multiple environments, I want commands and file operations to execute in the destination environment, so that the browser's machine never substitutes for the machine that owns my project.
  13. As a user, I want existing provider integrations to start, stream, cancel, and resume turns correctly, so that adopting Bun does not reduce my choice of provider.
  14. As an agent, I want MCP tools and self-launched ACP bridges to remain reachable, so that the new runtime does not break agent access to application capabilities.
  15. As a terminal user, I want input, output, resize, exit status, and cancellation to keep working, so that terminal sessions remain useful and do not leak subprocesses.
  16. As a user, I want project file search to retain its existing native behavior, so that the migration does not silently remove search capabilities.
  17. As a user authenticating a provider, I want credential storage and keychain access to continue working, so that I can keep using existing sign-in methods.
  18. As an Antigravity user, I want the sign-in URL relayed to my connected client, so that authentication continues to work without a first-party Node helper requirement.
  19. As a Browser panel user, I want server-hosted browser streaming and interactions to remain available, so that removing Electron and changing runtime do not remove the existing web browser surface.
  20. As an agent using Browser tools, I want inspection, screenshots, recordings, and other supported automation operations to continue server-side, so that browser work can proceed without an attached client.
  21. As a Device panel user, I want the pinned device hub and automation tools to install and run with Bun, so that simulator and device support survives independently of the removed mobile client.
  22. As an agent using Device tools, I want the pinned agent-device launcher and its session/configuration checks to remain correct, so that automation uses the intended tool version and target.
  23. As a user connecting a Device host over SSH, I want remote bootstrap to use Bun instead of requiring Node and npm, so that a Bun-only device host can provide its supported capabilities.
  24. As a user running unattended work, I want scheduled tasks and the environment server to keep running without a connected browser, so that the web-only client does not change execution ownership.
  25. As a service user, I want installation, start, stop, restart, update handoff, and failed-update recovery to remain reliable, so that I can operate an environment in the background.
  26. As an installed user, I want release discovery and updates to use my fork's artifacts, so that updating cannot replace iglo.code with upstream T3 Code or its Node runtime.
  27. As a user on an unsupported platform, I want a clear explanation of supported targets, so that I do not receive an incompatible archive or an unexplained startup failure.
  28. As a maintainer, I want diagnostics and errors to describe the actual Bun application/runtime requirements, so that troubleshooting does not incorrectly ask users to install Node.
  29. As a maintainer, I want source and compiled-artifact compatibility demonstrated with focused behavioral tests, so that a successful metadata command is not mistaken for a working application.
  30. As a maintainer, I want automated regression coverage in a real web client connected to Bun-hosted environments, so that passing server tests cannot conceal broken pairing, thread rendering, terminal interaction, or reconnect behavior.

Implementation Decisions

  • Baseline and platform scope: Desktop removal is a completed prerequisite, not work in this issue. The supported release targets are macOS arm64, Linux x64, and Linux arm64, preserving the existing non-Windows archive coverage. Adding Intel macOS or additional operating-system/libc targets is separate work. Unsupported targets receive an explicit error and are excluded from release selection.
  • Runtime contract: Pin one Bun version consistently for development runtime checks, application packaging, and runtime compatibility CI. Choose the minimum supported version from successful focused validation; the research probe used Bun 1.4.0 but did not establish full application compatibility. Do not retain a Node production runtime or automatic Node fallback.
  • Toolchain boundary: Keep Vite+, pnpm, and the existing test framework unless a concrete compatibility requirement demands a local adjustment. Update first-party server, CLI, development, and helper launch commands to Bun. Node used internally by retained contributor tooling or required independently by a provider is outside the application's runtime guarantee; state that distinction clearly rather than claiming every tool on the machine becomes Node-free.
  • Architecture and contracts: Keep execution in the owning environment. Preserve the pure orchestrator, transactional event/projection/receipt/outbox commit, and post-commit effect worker. Preserve persisted data formats and authenticated HTTP/WebSocket/MCP contracts. This migration does not require a protocol version change, data reset, or schema redesign.
  • Host process and executable detection: Replace the unconditional Node SEA dependency with Bun-aware source-versus-compiled detection. Keep application self-invocation distinct from invoking arbitrary JavaScript. Source launches must identify Bun plus the correct entrypoint; compiled launches must invoke their embedded CLI with the correct subcommand arguments. Preserve working-directory, environment, and argument handling for provider children, ACP bridges, service children, and hidden CLI commands.
  • General-purpose helper runtime: Replace the Node-specific resolver and error messages with a Bun helper-runtime contract at the existing shared boundary. Source execution can use the running Bun interpreter. A compiled application cannot be assumed to interpret arbitrary scripts; package a pinned Bun interpreter alongside the CLI if the compiled executable cannot provide that capability. Do not discover or download Node as a fallback.
  • Effect and HTTP: Initially preserve the current Effect service boundaries, compatible Node HTTP/stream APIs, and SQL integration. Replace an implementation only when validation identifies an incompatibility. If Bun-native HTTP or platform layers are introduced, ensure one coherent Effect module graph in both source and compiled builds. Pairing cookies, OAuth responses, CORS headers, compression, WebSocket upgrades, request cancellation, and finalizers are observable acceptance requirements.
  • SQLite and persistence: Validate the existing node:sqlite-based implementation under Bun before replacing it. Replace Node-version assumptions with checks of the capabilities actually required. Preserve prepared-statement results, positional values, large integers, SQLite error classification, WAL/locking behavior, transactions, migration/replay, and legacy snapshot import. A basic SELECT probe is insufficient proof of database compatibility.
  • PTY boundary: Validate the exact pinned node-pty package under Bun on supported targets. Keep it if it works. If it does not, provide a Bun implementation behind the existing PtyAdapter interface, preserving terminal behavior and cleanup without changing orchestration. Do not infer incompatibility from the package name or rewrite terminal management preemptively.
  • Native and disk-backed dependencies: Verify native search, keyring access, provider SDK chunks, browser automation dependencies, and native/resource-monitor assets under source and packaged execution. Preserve required external files in the archive. Compiling JavaScript does not make dynamically loaded native packages or Chromium disappear.
  • Providers: Cover every provider supported by the fork at implementation time. Preserve adapters and their native protocol behavior; use existing replay fixtures for deterministic coverage and appropriate real-process smoke checks for runtime-sensitive integrations. Provider-specific prerequisites must remain specific to that provider rather than causing a generic application requirement for Node.
  • Antigravity: Run the sign-in URL relay helper with Bun and retain its current BROWSER override, authorization URL marker, isolated profile, preflight check, and cancellation/error behavior. Remove the installer preflight's assumption that this helper needs Node. The small relay script passed an isolated Bun probe; that is not proof that the entire authentication flow has already been validated.
  • Local Device tooling: Preserve the Device panel. Install the pinned expo-device-hub and agent-device packages using Bun, launch their entrypoints with the helper runtime, and retain tool installation locking/staging, version pinning, session/configuration requirements, daemon isolation, and cleanup. Account for required package lifecycle scripts and nested helper launches, including daemon startup and maintenance, so a top-level Bun launch cannot conceal a later Node/npm dependency. Validate the complete pinned packages under Bun; the current T3 launch code does not by itself prove or disprove their compatibility.
  • Remote Device tooling: Update the SSH bootstrap's explicit node invocation, Node version check, npm prerequisite, package installer, and child launches to the Bun contract. The remote device host must have a supported Bun interpreter available; retain actionable non-interactive SSH PATH errors and existing Xcode/Android SDK prerequisites. Do not add an unrelated remote runtime provisioning system.
  • Browser and remote access: Preserve the existing server-owned Chromium/browser streaming and agent automation paths. Runtime migration does not restore Electron-only browser conveniences, desktop SSH provisioning, native screenshot capture, or other removed shell integrations. Chromium remains a separate browser dependency. Retain single-origin development behavior and compatible local/remote/tunnel connections.
  • Distribution and updates: Replace Node SEA compilation with Bun executable packaging for the supported targets. Retain the CLI subcommand and archive layout contracts where possible, including the web client, necessary native assets, helper interpreter, version metadata, and checksums. Make release API discovery, download URLs, installer defaults, service pinning, and updater defaults consistently target iglo-tech/iglo.code. Preserve explicit release-origin overrides. If fork artifacts are unavailable, report that condition rather than falling back to upstream releases.
  • Service lifecycle: Preserve process IPC or adapt it locally if Bun's behavior requires it. Validate service start/stop/restart, update commit/handoff, database backup/restore, and rollback through observable process and persisted-state outcomes. Keep the existing lifecycle protocol and service responsibilities rather than inventing a new supervisor.
  • Documentation and CI: Update affected user setup/troubleshooting guidance and maintainer runtime/release procedures where their documented requirements change. Add focused Bun source/artifact checks and automated real-browser web-client regression coverage for supported targets, with no Windows requirement. Keep implementation explanations close to the relevant code; do not add a second feature inventory or permanent research checklist.
  • Completion: Source and packaged execution must satisfy the same application behavior, including automated web-client regression coverage against each launch form; a source-only experiment is an implementation milestone, not completion of this issue. No mandatory first-party Node launch, npm Device bootstrap, Node SEA packaging, or default upstream runtime download may remain in the supported application paths.

Testing Decisions

  • Primary acceptance seam: Extend the existing CLI archive smoke harness into one reusable externally driven environment check. Launch either the source CLI with Bun or an extracted compiled archive in an isolated T3 home, then exercise the public CLI and authenticated HTTP/WebSocket/MCP interfaces. Connect the automated web-client regression suite to those same environment fixtures rather than creating a second server setup or new production test interfaces. Add only the fixture support needed to select the launch form and provide deterministic provider/device dependencies.
  • What makes a good test: Assert outcomes a client, agent, or operator can observe: correct responses and headers, persisted/replayed state, streamed output, process exit and cleanup, authenticated tool behavior, and successful service handoff. Do not assert import names, runtime brand strings alone, internal call counts, or a rewritten implementation's own structure. Running the existing tests only in a Node-hosted test process does not prove that the application works under Bun.
  • Source and artifact coverage: Exercise actual Bun application execution in both forms. Run the extracted archive outside the repository without repository dependencies or Node/npm available on PATH. For compiled core startup, also exclude system Bun to prove that the archive is self-contained; for helper execution, use its packaged interpreter. Supply explicit paths or controlled fixtures for unrelated OS/provider tools as needed. Verify more than --version: start the server, serve the client, open the database, and perform authenticated API work.
  • Transport regression: Reuse existing HTTP/auth/MCP and RPC contract tests, adding packaged-runtime coverage for pairing/session cookies, relevant CORS/compression headers, OAuth redirects/responses, WebSocket upgrade, subscriptions/reconnect, and cancellation. Include a cross-origin header case where the server actually permits it, so missing headers cannot be hidden by local single-origin development. This directly targets the historical Bun/Effect packaging regression.
  • Automated web-client regression: Require a reproducible automated suite in a real browser against the actual web client and Bun environment, using the development client for source execution and the archive's shipped client for compiled execution. It must run locally and in CI and assert visible behavior rather than static markup, mocked network wiring, or component props. Reuse the fork's supported browser automation infrastructure and its built-in Browser-panel verification workflow where applicable; if a durable regression runner is absent, add the smallest runner at this external client/server boundary. Existing connection supervisor/onboarding/compatibility, thread workflow/synchronization, and server Browser streaming tests provide focused client-state prior art but do not substitute for the real-browser suite.
  • Required web flows: Cover fresh pairing and session persistence across reload; loading representative existing projects/threads; submitting a deterministic provider turn and rendering streamed text/tool activity; cancellation and settled state; terminal input/output, resize, exit, and errors; server disconnect/restart/reconnect with restored history and no duplicate turn content; connection/settings state; provider sign-in URL/error presentation with controlled fixtures; and the Browser and Device panel's supported ready/unavailable/error flows. Include a client on a distinct origin and a multiple-environment case so remote routing and destination ownership are exercised. Use replay/fake provider and device-host fixtures for unattended tests; do not require paid subscriptions, live OAuth credentials, physical devices, or user interaction to pass the core web suite.
  • Browser test reliability and evidence: Use fresh client storage, disposable server state, stable semantic locators, and observable UI/protocol milestones. Avoid fixed sleeps and implementation-coupled snapshots. Capture useful failure artifacts such as a screenshot, browser console output, and server logs, excluding pairing credentials and secrets. Preserve one integrated pass through the project's supported Browser panel for user-visible implementation changes; that review does not replace automated regression coverage.
  • Persistence regression: Reuse SQLite transaction/result/error tests and orchestration replay/migration fixtures. Prove state persists across a Bun server restart, accepted commands and outbox effects settle correctly, lock contention fails predictably, and legacy snapshot import remains usable. Await drainable workers, persisted events, receipts, or Deferred milestones; do not introduce timing sleeps or polling assertions for domain completion.
  • Focused boundary tests: Retain and adapt the existing host-runtime/self-invocation, PTY adapter, Antigravity auth/installation, Device toolchain/local/SSH host/shim, service launcher, pinned-release installer, and release-selection tests. Add cases only where the high-level acceptance seam cannot isolate an important failure, such as selecting a helper interpreter from a compiled install or preserving a PTY resize/exit contract. These are existing boundaries, not a new test seam per module.
  • Providers and processes: Use existing provider replay/integration fixtures for each supported provider's relevant streaming, cancellation, restart/resume, and tool paths. Add targeted native/process smoke evidence for SDK loading, shell/PTY operation, native search, keyring access, and ACP bridge self-launch. Keep credential-dependent checks explicit; do not claim fixture coverage proves every live provider sign-in flow.
  • Device and Browser: Reuse Device service/MCP/SSH bootstrap fixtures and server Browser/context/streaming tests. Include supported simulator/device operation evidence on hosts with the relevant SDKs and a Bun-only remote bootstrap check. Verify browser automation and stream readiness through existing services and protocol boundaries, and include their relevant user-visible states in the automated web-client suite.
  • Service and release lifecycle: Reuse service launcher and pinned-runtime installer tests with local controlled release fixtures. Verify checksums, fork release selection, start/stop/restart, update handoff, failed-update recovery, and cleanup using built Bun artifacts. Tests must not install a real system service or update a live environment.
  • Isolation and scope: Use disposable homes, fixture projects, tracked child PIDs, and read-only snapshots when real data is useful. Never write to the maintainer's live T3 home or start providers against it. Run only the focused test/typecheck/lint scopes affected by the implementation locally, including the scoped web-client regression suite; CI owns the full suite. Automated web-client regression is explicitly required by this specification. This issue-creation task does not itself implement tests, start application servers, or launch a browser.
  • Performance evidence: Record a small repeatable baseline and Bun comparison for startup, idle memory, and representative terminal/provider/transport work where available. Investigate material regressions. The acceptance criterion is preserved behavior and operability; the research does not justify promising that Bun will be faster or expanding this into a benchmarking project.

Out of Scope

  • Removing desktop code or reintroducing the native mobile client; both are assumed already removed.
  • Windows support, Intel macOS release expansion, or a maintained Node/Bun dual-runtime matrix.
  • Migrating the whole workspace from Vite+/pnpm to Bun's package manager, task runner, bundler, or test runner merely for consistency.
  • Rewriting working Node-compatible APIs, Effect services, SQL, provider orchestration, or the client application solely because Bun is the runtime.
  • Eliminating independently documented prerequisites of third-party provider CLIs, Xcode, the Android SDK, Git, Chromium, or native build/operating-system tools.
  • Removing the Device panel or server Browser feature, replacing them with desktop/mobile features, or restoring Electron-only conveniences.
  • Changing authentication/scopes, wire contracts, persisted data formats, or provider capabilities as a product redesign.
  • Adding a new supervisor, remote runtime provisioning system, general compatibility framework, or extensive benchmark infrastructure.
  • Implementing the migration, cutting a release, opening a PR, or deploying changes as part of creating this specification.

Further Notes

This specification assumes a post-desktop-removal repository. The research checkout still contained desktop references; implementation should inspect the actual remaining repository rather than recreating removed code or treating desktop cleanup as part of this issue.

The research found concrete migration work, not evidence that Bun is inherently unsuitable:

  • Upstream PR #2098 motivated the earlier Node development runner switch with Windows support.
  • Upstream PR #11316 consolidated standalone distribution around Node and removed the separate Bun runtime implementations. Desktop runtime reuse and distribution simplicity explain upstream's choice; they are not functional requirements of this web-only fork.
  • Upstream PR #2899 separately changed workspace tooling to Vite+/pnpm. Application runtime and contributor toolchain are distinct decisions.
  • Upstream issue #7756 and proposed PR #9118 exposed missing cookies/CORS/compression caused by separate Effect module graphs in Bun packaging. The proposed fix was not merged; test the final artifact rather than assuming the regression is resolved.

Isolated research probes on Bun 1.4.0 established that importing node:sea fails, a small node:sqlite query and the statement capabilities examined are available, and Antigravity's exact URL relay helper produces the same output as Node for a fake authorization URL. No full Bun-hosted server, compiled release, live provider sign-in, or pinned Device package was validated during the research. Native package compatibility and overall runtime performance remain implementation validation tasks.

Use the smallest changes that satisfy this specification. Prove source compatibility first, then packaged helper/self-invocation behavior and service/update operation. Historical Bun implementations can inform an adapter replacement if one is needed; they should not be restored wholesale without checking current behavior.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-for-agentSpecified and ready for agent implementation

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions