Fix frontend dev server start on bun-only Windows installs

Merged
FA
2d ago
+122-31

Type of change

  • Bug fix (non-breaking change which fixes an issue)

What

On Windows with bun and no Node.js, reflex run could not start the frontend:

[restart] Relaunching with --conditions=development
error: restartWithMergedOptions() was called, but the process has already been restarted.

react-router dev needs the development export condition and relaunches itself to enable it. NODE_OPTIONS only reaches real Node, so a bun-only install depends on that relaunch. On Windows the relaunched process receives the flag but still does not apply the condition, so the CLI tries to relaunch again and trips its guard.

Fix

When bun is the runtime (no Node, or an outdated one), the dev server is started with

bun --conditions=development run --bun react-router dev --host

instead of bun run dev. Bun applies the condition itself, so the CLI never relaunches. With a supported Node installed the command is unchanged (bun run dev / npm run dev), and Node still reads the condition from NODE_OPTIONS.

run_frontend and AppHarness now share a private _frontend_dev_command() helper in reflex/utils/exec.py. The script is taken from constants.PackageJson.Commands.DEV rather than a hardcoded path into @react-router/dev.

Testing

On Windows 11, bun 1.4.4, no Node, react-router 8.4.0:

  • tests/integration/test_nodeless_frontend.py failed before the change with the error above and passes after. It also asserts that the dev server got --conditions=development, so it checks the new command on Linux CI too, where bun run dev already worked. Its fixture stubs the per-process node probe, so an earlier test that found node cannot change the command.
  • New parametrized test_frontend_dev_command pins the exact command for each runtime case.
  • reflex run on a minimal app starts and serves the page.
  • ruff check and ruff format are clean.

Reviewer notes

  • Not run locally: the full unit and integration suites. Pyright is clean.
  • The new command also applies to bun-only Linux and macOS, where bun run dev already worked; I could only test Windows, so CI's node-less integration test is the coverage there.
  • The outdated-Node case previously ran bun --bun run dev and now takes the same direct form. That path is only unit-tested.
  • run_process_and_launch_url now takes list[str] instead of list[str | None]. No caller passes None, and new_process already exits on a None argument.
  • Why bun's stand-in node.exe ignores the flag on relaunch is not investigated; this sidesteps it.

closes #7894