Releases: reflex-dev/reflex
Release list
v0.9.7
reflex v0.9.7 ships alongside reflex-base 0.9.7, reflex-components-core 0.9.7, reflex-components-radix 0.9.6, and reflex-docgen 0.9.3.
Features
ArrayVargainedmap,filter,reduce, andflat_mapfor transforming array vars directly on the frontend. (#6701)rx.Configgaineddefault_color_mode("system","light", or"dark", also settable viaREFLEX_DEFAULT_COLOR_MODE), letting apps set the initial color mode โ and use the built-in color-mode switcher andrx.color_mode_condโ without pulling in the large Radix themes CSS. It drives both the compiledThemeProviderdefault and the pre-hydration preload script, so there's no flash of the wrong theme on first paint; an explicitrx.theme(appearance=...)still takes precedence. (#6716)rx.Configgainedfrozen_lockfile(defaultTrue, also settable viaREFLEX_FROZEN_LOCKFILE). When enabled, bun's initial install runs with--frozen-lockfileso a lockfile out of sync withpackage.jsonfails fast; set it toFalseto let the lockfile update in place. (npm has no equivalent install flag, so it's a no-op there.) (#6763)@rx.memoaccepts awrapper=argument controlling the JS function that wraps the compiled component: React'smemo(the default), a custom functionVarwhose imports ride along into the generated module, orwrapper=Noneto emit the bare function component. (#6730)
Bug Fixes
- Fixed stateful pages being evaluated twice in one process (forked production workers, and same-process export+serve), which created duplicate
ComponentStateclasses and broke frontend hydration (TypeError: d is not a function). (#6710) - Custom attributes are now preserved in more places โ on a
Fieldwhen the state metaclass rebuilds it (#6726), and on event handlers and computed vars inherited from a state mixin, along with their keyword-only defaults (#6725). RedisTokenManagernow closes its redis client and cancels its pub/sub tasks on shutdown, fixing leaked redis connections (ResourceWarning: unclosed Connection) when the server stops. (#6724)- Fixed
_get_all_hooks_internalmutating each component's cached hooks with its descendants' hooks, which made memo tag hashes order-dependent and duplicated hooks into memo bodies. (#6741) - The disk state manager resets its write-queue task after close. (#6715)
reflex-docgenno longer misinterpretsmeta_description/descriptionfrontmatter keys as component preview lambdas. (#6704)
Performance
- Telemetry now runs on a dedicated background thread instead of inline on the asyncio event loop, so its blocking syscalls, subprocess calls, and synchronous HTTP request no longer stall the loop โ notably when reporting backend errors at a high rate. Delivery is best-effort and failures are suppressed, so telemetry can never affect the running app. (#6626)
- Event chaining (
yield OtherState.handler(rows)) no longer deep-copies payload values that aren't attached to any state โ only state-boundMutableProxysubtrees are copied, making proxy-free payloads ~5x faster to chain. (#6739) Var.to()andVar.guess_type()use cached registry lookups instead of scanning the full registry withsafe_issubclasson every call (~70% of the cost of constructing a var operation). (#6742)console.deprecatecaches framework-path checks in its call-stack walk, making repeat calls ~150x faster โ deprecated attributes on hot paths (likeRouterData.page) no longer cost milliseconds per access. (#6736)
Deprecations
ArrayVar.foreachis deprecated in favor ofArrayVar.map. (#6701)
Full Changelog: v0.9.6...v0.9.7
v0.9.6.post2
hot fix: Add frozen_lockfile config to control bun lockfile enforcement (#6763)
v0.9.6.post1
hot fix: ENG-9923: Add REFLEX_EXTRA_PLUGINS env var to append to plugin list (#6685)
v0.9.6
reflex v0.9.6 ships alongside reflex-base 0.9.6, reflex-components-core 0.9.6, reflex-components-moment 0.9.2, and reflex-components-plotly 0.9.3.
Features
rx._x.hybrid_propertynow works on dataclasses, Pydantic models, and SQLAlchemy models, not justStateclasses. Accessed through an object var on the frontend (e.g.State.info.a_b), it renders as a var using the same code as the backend โ and now raises a clear error if the frontend logic reads a backend (underscore-prefixed) var instead of silently baking in the server-side default. (#6617, #6621)- Auto-memoized (
rx.memo) components now compile to per-module output paths. Each emits to a.web/app_components/path mirroring its defining Python module instead of a single sharedcomponents.jsx, so identically-rendered subtrees in different modules no longer overwrite each other and same-named memos across modules can coexist on one page. (#6457) reflex initnow writes a managedAGENTS.mdsection (preserving your surrounding content) and bridges it to Claude Code via aCLAUDE.mdthat imports@AGENTS.md. (#6620)StringVargainedlstripandrstrip, andstripnow accepts an optionalcharsargument, matching Python'sstrAPI. (#5417)rx.plotlyaccepts alocaleprop to localize number/date formatting and modebar labels; the matchingplotly.js-localesdata is resolved and merged automatically per chart. (#6428)package.jsongeneration accepts extra keys.package_json_templatetakes**additional_keys(e.g.name,packageManager,engines), andreflex.lock/package.jsonis now synced to.web/package.jsonbefore install so the manifest and lockfile stay aligned. (#6658)
Bug Fixes
- ๐ Security โ minimum dependency versions raised (#6665):
starlette >= 1.3.1โ Host-header path poisoning,request.form()DoS, and UNC-path SSRFpython-multipart >= 0.0.32โ querystring DoS, unbounded header field size, and negativeContent-Lengthbuffering inparse_formgranian >= 2.7.4โ WSGI and WebSocket header-panic DoS- bundled
viteโ8.0.16โserver.fs.denybypass on Windows alternate paths (CVE-2026-53571)
- Bound arguments now pass through to upload handlers, so
on_drop=State.handle_upload(rx.upload_files(...), field)forwardsfieldto the backend instead of raising a missing-argument error. (#5290) rx.condpreserves literal string types, sorx.cond(State.flag, "green", "red")infersVar[Literal["green", "red"]]instead of widening toVar[str]โ fixing Pyright errors on props like Radixcolor_scheme. (#6545)rx.debounce_inputno longer crashes withReferenceError: input is not definedwhen wrapping a native DOM element such asrx.el.inputorrx.el.textarea. (#6637)rx.momentpinsmoment-timezoneto exactly0.6.2(instead of a caret range) for reproducible frontend installs. (#6649)modify_staterebinds the event token correctly, so delta resolution and computed vars in shared-state fan-out tasks observe the right client token. (#6673)- Avoid re-entering config loading when a
Statesubclass is defined inrxconfig.py. (#6662)
Miscellaneous
pyi_hashes.jsonentries are now computed from the final.pyicontent (afterruff format/ruff check --fix), so formatting-only generator changes no longer flag spurious hash changes.
Full Changelog: v0.9.5.post2...reflex-components-core-v0.9.6
reflex-hosting-cli@0.1.67
Features
- Added a
--service-accountflag toreflex deploy --gcp, letting Cloud Run services run as a least-privilege per-service service account instead of the project's default compute SA. (#6556) - Added
--max-instances,--allow-unauthenticated/--no-allow-unauthenticated,--env KEY=VALUE, and--envfileflags toreflex deploy --gcp, letting you cap Cloud Run autoscaling, deploy a private service, and set environment variables at deploy time. (#6557) - Added
reflex cloud scan, which uploads your app source for a Reflex-aware security review and reports security and logic flaws. Supports--jsonoutput and a--fail-onseverity gate for CI. (#6632)
v0.9.5.post2
A patch on top of v0.9.5.post1 (reflex-base 0.9.5.post2 released in lockstep, no separate changes).
Bug Fixes
- Allow access to
Statefromapp_wrapcomponents. (#6651)
Full Changelog: v0.9.5.post1...v0.9.5.post2
v0.9.5.post1
A compatibility patch on top of v0.9.5 (reflex-base 0.9.5.post1 released in lockstep, no separate changes).
Bug Fixes
- Bumped the minimum
reflex-components-coredependency to 0.9.5 for compatibility.
Full Changelog: v0.9.5...v0.9.5.post1
v0.9.5
reflex v0.9.5 ships alongside reflex-base 0.9.5, reflex-components-core 0.9.5, reflex-components-radix 0.9.5, and reflex-components-lucide 1.0.2.
Features
- Typed form submissions.
rx.form'son_submithandler can now annotate its form-data parameter with aTypedDict(includingtyping_extensions.NotRequiredfields). At build time the form statically validates that its controls supply every required field โ raisingEventHandlerValueErrorwith the missing/present field names โ andinput/select/textareaplus the Radix form controls (checkbox, checkbox group, radio group, radio cards, select, switch, and both sliders) are recognized as field contributors. Validation is skipped when the form sets anidor any control identifier is a dynamicVar. (#6301) - Event handlers on out-of-scope JSX literals now dispatch. Handlers attached to JSX built outside a component's render scope โ e.g. an
ErrorBoundary'sonErrorโ can now dispatch events; the state and event-loop providers are injected around the app root by the compiler rather than depending on a hoisted hook. (#6447) App.hydrate_fallbackrenders a component during the page's hydration window (React Router'sHydrateFallback) instead of a blank white page. Also configurable without code via thehydrate_fallbackconfig /REFLEX_HYDRATE_FALLBACKenv var. (#6630)REFLEX_HOT_RELOAD_OVERRIDE_PATHSenv var fully replaces the paths watched for hot reload in dev mode. (#6639)
Bug Fixes
State.router.urlno longer reflects a stale query string after the URL is changed viawindow.history.replaceState/pushState(e.g. fromrx.call_script); query and hash are now read from the livewindow.location. (#6625)- Frontend-only events from middleware
preprocessnow fire.rx.toast/rx.redirectreturned from a middleware'spreprocessare emitted to the client instead of being enqueued on the backend and raisingKeyError. (#6644) State.get_var_value()raises instead of returning a wrong value when passed a Var operation such asState.a + State.borState.items[0]โ nowUnretrievableVarValueError. (#6633)- Anonymous telemetry identifiers are now UUID strings, not 128-bit integers that PostHog truncated to floats (risking distinct installs being correlated as one); a one-time
$create_aliaspreserves history. (#6611) - Underscore-prefixed props are no longer emitted into generated
.pyifiles. (#6628)
Performance
rx.iconno longer pulls in the entire ~1700-icon library. Static-name icons now emit deep per-icon imports (lucide-react/dist/esm/icons/<name>.mjs), so once an app's module graph also containslucide-react/dynamic.mjs(e.g. the connection overlay) pages no longer fetch every icon chunk. (#6628)- ~3โ4ร faster reads of mutable state vars (lists, dicts, dataclasses) through
MutableProxy. (#6600) - Faster component creation via lazy field-default resolution, cached event triggers, and a memoized
to_camel_case. (#6576)
Miscellaneous
- Anonymous telemetry now reports the versions of the first-party Reflex subpackages (
reflex-base, thereflex-components-*family,reflex-hosting-cli) via a newreflex_package_versionfield. (#6610) pyi_hashes.jsonmaintenance hardened:scripts/make_pyi.pyis now a proper CLI (--force,--check, merge-not-prune), and the build-hook entrypoint no longer wipes the hash registry when building a single package. (#6614)
Full Changelog: v0.9.4...v0.9.5