reflex v0.9.8 ships alongside reflex-base 0.9.8, reflex-components-code 0.9.3, reflex-components-core 0.9.8, reflex-components-lucide 1.0.3, reflex-components-moment 0.9.3, reflex-components-plotly 0.9.4, reflex-components-radix 0.9.7, reflex-components-recharts 0.9.2, and reflex-docgen 0.9.4.
Features
- New
previewrun mode (reflex run --env preview) hot reloads likedev, but serves a freshly built frontend bundle mounted into the backend instead of running the Vite dev server. Minification, CSS minification, autoprefixer, and sourcemaps are all off by default for faster rebuilds and readable output, each overridable viaVITE_MINIFY,REFLEX_NO_AUTOPREFIXER, andVITE_SOURCEMAP. (#6663) rx.assetURLs now carry a short content hash (rx.asset("logo.svg")β/logo.svg?v=a1b2c3d4), so browsers refetch an asset only when its contents actually change. (#6550)- Mutable state values can be used as async context managers, so a helper that receives only the value can refresh it from its owning state and hold the same exclusive lock as
async with self. Root mutable fields and nested values reached through stable dict keys or object attributes are supported; values taken from list indexes, slices, iteration, or a missingdict.get()default can't be re-identified after concurrent state changes and raiseRuntimeError. (#6689) - Plugins can contribute pages through a new staged
Plugin.register_routehook, which runs once per app before page evaluation β withadd_pageandhas_app_pagecapabilities β so a plugin's pages land atomically, and the cached route resolver is invalidated when a page is added after it was first built.rx.plugins.get_plugin()looks up a configured plugin instance by type, raisingConfigErroron ambiguous matches. (#6728) reflex deploygained--provider(deploy to Reflex Cloud or a GCP account connected to your organization) and--description(record an optional changelog note on the deployment, shown inreflex cloud apps history). (#6810)rx.recharts.layerandrx.recharts.rectanglewrap the RechartsLayerandRectanglecomponents, used for constructing custom node elements. (#6729)reflex-docgengained typeddescriptionandimagefrontmatter fields onFrontMatter, parsed from docs and preserved by the markdown writer, for per-page SEO metadata. (#6464)
Bug Fixes
- Two Windows-only frontend failures are fixed β nested/subfolder stylesheets failed to load because the generated CSS
@importused backslash path separators (which CSS treats as escape sequences), so the import URL is now always POSIX-normalized (#6762); and production frontend hydration broke when the system MIME registry maps JavaScript files totext/plain(#6831). - Fixed
reflex runfailing witherror: lockfile had changes, but lockfile is frozenafter upgrading to a Reflex version that adds apackage.jsonoverride. A persistedreflex.lock/package.jsonis now restored as-is and the framework-owned overrides are merged into.web/package.jsonafter the frozen install, so the restored package.json/lockfile pair is no longer treated as out of date (#6844). Persistedpackage.jsonfiles are also processed before being mirrored into the web directory (#6765). reflex renameno longer corrupts or fails on source files under non-UTF-8 platform locales, while preserving declared Python source encodings and line endings. (#6761)- Fixed
reflex component buildcrashing withAttributeErroron Python 3.10 and 3.11, by delegating recursive stub generation to the Python 3.10-compatiblePyiGeneratorscanner. (#6760) - Event processor shutdown is cleaner β queued same-token events are drained during a graceful shutdown (#6791), and on Python 3.13+ the loop catches the native
asyncio.QueueShutDowninstead of surfacing uncaught exceptions while stopping (#6773). - Editing a route that hasn't been loaded yet no longer poisons React Router's browser-side HMR queue, which previously blocked every later hot update until a full page reload. (#6774)
- Unannotated
@rx.memocomponent parameters keep their runtime value types. (#6659) - Timezone-aware datetime Vars compare by their instants instead of by their serialized UTC offsets. (#6767)
- Custom attributes on a
Fieldare now carried onto the rebuilt field by reference instead of deep-copied, so stateful callable markers keep their identity and markers holding non-copyable values (locks, clients) no longer crash state class creation. (#6809) rx.momentis now aMemoizationLeaf, so a statefuldatechild is no longer memo-wrapped β react-moment parsed the wrapped value likemoment({})and rendered today at midnight. (#6784)
Miscellaneous
-
Bundled frontend and component-library dependency pins were bumped to their current releases (#6678):
react/react-dom: 19.2.6 β 19.2.8react-router,react-router-dom,@react-router/node,@react-router/dev,@react-router/fs-routes: 7.15.0 β 7.18.2vite: 8.0.16 β 8.2.0,postcss: 8.5.14 β 8.5.23,autoprefixer: 10.5.0 β 10.5.4isbot: 5.1.40 β 5.2.1,universal-cookie: 7.2.2 β 8.1.2,@tailwindcss/typography: 0.5.19 β 0.5.20- Bun: 1.3.13 β 1.3.14
lucide-react: 1.14.0 β 1.26.0, adding 46 new iconsreact-plotly.js: 2.6.0 β 4.0.0, withplotly.js(and its dist-min / locale variants) 3.5.x β 3.7.0shiki/@shikijs/transformers: 3.3.0 β 4.3.1react-error-boundary: 6.1.1 β 6.1.2- Radix primitives β
@radix-ui/react-accordion: 1.2.12 β 1.2.18,@radix-ui/react-dialog: 1.1.15 β 1.1.21,@radix-ui/react-form: 0.1.8 β 0.1.14,@radix-ui/react-progress: 1.1.8 β 1.1.14,@radix-ui/react-slider: 1.3.6 β 1.4.5
The
richupper bound also rose to<16(adopting rich 15). The now-redundantcookiepackage.jsonoverride (universal-cookie8 andreact-routerresolvecookieto 1.x on their own) was replaced with apostcssoverride pinning 8.5.23 β which also satisfiesvite8.2.0's^8.5.23β so transitive resolutions stay on a release patched for a security advisory (>= 8.5.18). -
Development-only dependency pins were updated to clear CVE reports:
Pillow==12.3.0(#6836), and lockedaiohttp==3.14.3/cryptography==50.0.0, clearing CVE-2026-59881, CVE-2026-69243, CVE-2026-69244 and CVE-2026-69247 (#6837). The latter two are transitive development dependencies of the docs app and are not installed with Reflex. -
The unused
REFLEX_USE_TURBOPACKenvironment variable was removed. Turbopack is a Next.js bundler; the flag has had no effect since Reflex moved to React Router and Vite in 0.8. (#6803)
Full Changelog: v0.9.7...v0.9.8