[vite 8.2.0] Fix REFLEX_ENV_MODE leak between AppHarness instances
Type of change
- Bug fix (non-breaking change which fixes an issue)
Description
Fixes a critical bug where AppHarnessProd leaked REFLEX_ENV_MODE=prod into subsequent dev AppHarness instances in the same process. When AppHarnessProd runs export(), it sets REFLEX_ENV_MODE=prod process-wide and never restores it. A dev AppHarness compiling later would then write prerender: true into its dev react-router config, causing the dev server to serve prerendered page HTML. On pages with hydration hazards, this failed hydration on every load and dropped events dispatched during the hydration-recovery window.
Root cause: The environment variable leak was masked by a vite 8.0.16 pin that was added to work around memo component re-rendering failures in the full integration suite. Those failures were actually caused by this REFLEX_ENV_MODE leak, not by vite itself.
Changes
-
reflex/testing.py: PinREFLEX_ENV_MODEtodevinAppHarness._initialize_app(), mirroring whatreflex rundoes. This ensures dev harnesses always compile in dev mode regardless of priorAppHarnessProdinstances. -
packages/reflex-base/src/reflex_base/constants/installer.py: Bump vite from 8.0.16 to 8.2.0 now that the root cause of the memo regression is fixed. -
Tests: Added
test_app_harness_initialize_resets_leaked_prod_env_mode()to verify that devAppHarnesscorrectly resetsREFLEX_ENV_MODEto dev mode and disables route prerendering, even when the environment variable was previously set to prod. -
News fragments: Added changelog entries documenting the bugfix and vite bump.
Update (2026-08-07): react-router 8.3.0 merge + docker-test fixes
Merged main (react-router 8.3.0 upgrade, #6854) into this branch so CI exercises the shipping combination, and fixed the two reflex-init-in-docker-test failures that upgrade introduced on main:
-
packages/reflex-base/src/reflex_base/compiler/templates.py: Pinpreview.hostto127.0.0.1in the generated vite config. react-router 8 prerenders by fetching pages from avite previewserver started with the project's config; with no pinned host, the bound socket and the fetchedhttp://localhost:<port>/URL can resolve to different loopback address families (as in docker containers), failingreflex exportwithPrerender: Request failed for /: ECONNREFUSED. Same fix TanStack Router shipped for the identical failure (TanStack/router#6305). Full diagnosis in this comment. -
reflex/utils/exec.py: Pre-enable thedevelopmentexport condition (NODE_OPTIONS/BUN_OPTIONS) when starting the dev server. react-router 8's dev CLI otherwise re-executes itself to enable the condition, which bun does not honor on installs without node, tripping the CLI's restart guard and exiting the dev server. Details in this comment.
Test Plan
- New regression test
test_app_harness_initialize_resets_leaked_prod_env_mode()verifies the env-mode fix - New unit tests assert the generated vite config pins the preview host, and that the development condition is merged into
NODE_OPTIONS/BUN_OPTIONS - Existing unit tests pass; memo playwright suites pass 10/10 on the merged react-router 8.3.0 + vite 8.2.0 tree
- Node-free verification (reflex-managed bun 1.3.14, mirroring the docker image): fresh
blankappreflex exportsucceeds, andreflex run --env devserves 200 with zero restart errors
https://claude.ai/code/session_01AzeRM83L6J367wmwk9Gezk
<img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg">