Breaking Changes
- The root state gained five base vars holding the router data:
rx_router_session,rx_router_headers,rx_router_page,rx_router_urlandrx_router_route_id. A substate that declares one of these names now raisesBaseVarShadowsInheritedVarError, the same error any other shadowed inherited var raises, and must rename its field.State.routeritself is unchanged. (#7068) - Declaring a substate var that shadows a var inherited from a parent state now raises
BaseVarShadowsInheritedVarErrorat class creation. Such a declaration was silently ignored — reads and writes resolved to the parent's var and class-level access returned the raw default instead of a reactiveVar. Rename the substate var to fix the error. (#7077) - State vars, event handlers, and dynamic route arguments now reject names reserved by framework methods and bookkeeping before registration. Rename conflicting members. (#7136)
Deprecations
- Declaring a computed var dependency on the
routervar (deps=["router"]) is deprecated; depend on the router Var instead, e.g.deps=[State.router.url]for a single field ordeps=[State.router]to keep tracking all of them. (#7068)
Bug Fixes
- Fix stateful inputs under
rx.form.control(..., as_child=True)so they receive the parent form's attributes and their values appear in submitted form data. (#6850) - Allow State Vars for page titles and descriptions in
@rx.pageand compiled metadata. (#6923) - Stopping
reflex runwith SIGTERM no longer reports "Starting frontend failed with exit code 143" and now exits cleanly. (#6981) - Preserve relationship serialization and database usage accounting for apps that use SQLModel directly, without loading unused database integrations. (#7049)
- Preserve prerendered pages when asset directories collide with routes under
frontend_path, and compress the final merged output. (#7078) - Generated
.pyistubs now type a prop declared as a union —content: Var[str] | Component, say — as optional, matching theNonedefault thatcreate()gives every prop. Type checkers previously reported the generated signature itself as an error. (#7080) - Subclassing
rx.Model(e.g.class Item(rx.Model, table=True)) without thedbextra installed now raises the guided "pip install reflex[db]"ImportErrorinstead of a bareTypeErrorfrom__init_subclass__. (#7083) - Backend-only development runs no longer leave a compile-skip marker that can cause the next full run to skip frontend compilation. (#7089)
- Persist bundled-library metadata for backend-only workers so state hydration can serialize values that reference libraries included in the frontend build. (#7096)
- Keep the development backend port open while hot reload restarts the worker, so requests made during a reload wait for the new worker instead of being refused. (#7114)
- Fixed local package specifiers such as
@masenf/hello-react@../hello-reactand@masenf/hello-react@../hello-react.tgzbeing truncated at the first slash (to@masenf/hello-react@..) before reaching the package manager, so wrapping a React package from a local directory or archive now installs correctly. (#7117) - Switching between bun and npm (
REFLEX_USE_NPM) no longer leavesreflex.lock/in a state that makes the next run fail withbun install --frozen-lockfile: lockfile had changes. Only the lockfile of the package manager that actually ran is kept. (#7129) - Keep saving state to disk and Redis when a state defines a var named
_get_was_touched. (#7132) - Apps no longer crash at startup with
AttributeError: 'method' object attribute '__call__' is read-onlywhen ASGI instrumentation that wraps middleware is active, such as sentry-sdk's Starlette integration. (#7139) - Fix backend startup crashes from concurrent or truncated stateful-page marker writes. Markers are replaced atomically, remain readable by separate backend users, and are rebuilt when missing or corrupt; dry-run compilation leaves them unchanged. (#7142)
- Match routes that start with the
frontend_pathtext, such as/appleunderfrontend_path="/app", instead of treating them as 404. (#7153) - Flush OpenTelemetry compile spans before the isolated initial development compile worker exits. (#7155)
- Fixed
StateManagerDisk.set_stateto persist and cache state instances that were not obtained fromget_state, and debounced writes now flush the latest supplied value instead of the first one queued. (#7159) - Fix
@rx.memocomponents dropping the app wraps their body requires. Providers
requested by a nested child, or through var data asrx.upload's
UploadFilesProvideris, now reach the app root — so a provider-backed
component behaves the same inside a memo as inlined into the page. (#7176) - Reuse one long-lived Redis client for the
/_healthendpoint instead of opening and closing a new TCP connection on every probe. (#7187) - Emit Granian lifecycle logs as JSON records when Reflex JSON logging is enabled, keeping
reflex run --jsonstdout valid JSON lines. (#7193) - Avoid crash when node is not installed (
error: restartWithMergedOptions() was called, but the process has already been restarted.). (#7202)
Performance
-
@rx.var(cache=False)vars now remember what they last sent to the frontend. They are still recomputed on every state update, but the value is only included in the delta when it actually changed, so an uncached var whose value stays the same no longer causes needless network traffic and re-renders. (#6946) -
Reduce development startup and reload time and memory by deferring unused database, admin, and compiler imports in the backend launcher and state mutation tracking, and by avoiding redundant app preloads in spawned Granian supervisors. (#7049)
-
Store router data in separate base vars (session, headers, page, url, route_id) so a navigation delta only re-sends the fields that changed instead of the whole router, and gather the connection-scoped router data (headers, client IP, session id) once at connect time rather than on every event.
State.routeris unchanged for app code.The page URL is also persisted as the URL itself rather than as its parsed pieces:
ReflexURLandURLDatare-split on the way out of the state store instead of writing scheme, netloc, origin, path, query, query parameters and fragment alongside the href on every state write. (#7068) -
Preload the global stylesheet so browsers can discover render-blocking CSS alongside early resource hints. (#7078)
-
Honor
frontend_lazy_bundled_librarieswhen compiling the app root so optional dynamic-component namespaces do not force their full exports into every page's initial bundle. (#7078) -
Reduce
reflex runandreflex exportmemory: the vite/react-router processes no longer keep their dependency pre-bundling arena resident (MIMALLOC_ARENA_EAGER_COMMIT=0, overridable from the environment), and error telemetry is sent throughurllibso backend workers never importhttpx. (#7112) -
Speed up compilation by reading only the props a component sets, caching literal Var dispatch by value type, and trimming render and app-wrap bookkeeping. (#7121)
-
Share one event chain per handler and trigger across call sites, and reuse memoized event wrappers by chain identity during compilation. (#7122)
Documentation
- Refresh the
docker-exampledeployments for current Reflex and consolidate them intoproduction,production-compose, andapp-platform-backend, with smaller images, clean SIGTERM shutdown, and no build tooling at runtime. The two-port example is gone since prod mode now serves the frontend and backend on one port; the self-hosting docs are updated to match. (#7140)