Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
## v0.9.5 (2026-06-10)

### Features

- `rx.form` `on_submit` handlers can now annotate their form-data parameter with a `TypedDict` (including `typing_extensions.NotRequired` fields). The submitted mapping is accepted by the event-argument type checker, and at component build time the form statically validates that its controls supply every required `TypedDict` field, raising `EventHandlerValueError` — with the missing and present field names — when a required field has no control with a matching static `name`/`id`. Validation is skipped when the form sets an `id` (controls may be associated externally via the HTML `form` attribute) or when any control identifier is a dynamic `Var`. ([#6301](https://github.com/reflex-dev/reflex/issues/6301))
- Event handlers attached to JSX literals built outside a component's render scope — such as an `ErrorBoundary`'s `onError` — can now dispatch events. `addEvents` is reached through a module-level import that `EventLoopProvider` populates on each render, so dispatch no longer depends on a `useContext` hook being hoisted into the calling scope. The state and event-loop providers, previously hard-coded in the layout template, are now injected around the app root by the compiler from the `app_wraps` declared on the `Var`s that use them. ([#6447](https://github.com/reflex-dev/reflex/issues/6447))
- Added `App.hydrate_fallback`, a component rendered during the page's hydration window (React Router's `HydrateFallback`) instead of a blank white page. It can also be configured without code through the `hydrate_fallback` config — a dotted import path to a no-arg callable returning a component, settable via the `REFLEX_HYDRATE_FALLBACK` environment variable — with the `App` argument taking precedence. Note that the fallback only covers the hydration window after the JS bundle has loaded, not the initial bundle download. ([#6630](https://github.com/reflex-dev/reflex/issues/6630))
- Added the `REFLEX_HOT_RELOAD_OVERRIDE_PATHS` environment variable, a colon-separated list of paths that, when set, fully replaces the paths watched for hot reload in dev mode — taking precedence over the config-derived defaults as well as `REFLEX_HOT_RELOAD_INCLUDE_PATHS` and `REFLEX_HOT_RELOAD_EXCLUDE_PATHS`. ([#6639](https://github.com/reflex-dev/reflex/issues/6639))

### Bug Fixes

- Anonymous telemetry now reports the installation and project identifiers as UUID strings rather than 128-bit integers. PostHog coerced the large integers to floats, discarding all but ~16 significant digits and risking distinct installs or apps being correlated as one. Each identifier is re-encoded to the same value (a UUID carries the same 128 bits), and a one-time PostHog `$create_alias` links an installation's pre-existing history to its new identifier so continuity is preserved. ([#6611](https://github.com/reflex-dev/reflex/issues/6611))
- `scripts/make_pyi.py` is now a proper CLI for maintaining `pyi_hashes.json`: `--force` regenerates every default target (ignoring the incremental markers), explicit targets are merged into the registry instead of pruning it, and an unreachable last-run commit (after a branch switch or rebase) triggers a full regeneration. A new `--check` mode, wired into the pre-commit CI job, fails when a `pyi_hashes.json` entry no longer has a matching `.py` source. ([#6614](https://github.com/reflex-dev/reflex/issues/6614))
- `State.get_var_value()` no longer silently returns a wrong value when passed a Var operation — an arithmetic/concatenation expression such as `State.a + State.b`, or an indexed/item access such as `State.items[0]`. Previously it resolved the state and field of the operation's *first* operand and returned that field's value instead of the operation's result. It now raises `UnretrievableVarValueError`, consistent with how it already handled vars not associated with any state. Plain field and computed-var references continue to resolve as before. ([#6633](https://github.com/reflex-dev/reflex/issues/6633))

### Performance

- Speed up reading mutable state vars (lists, dicts, dataclasses) through `MutableProxy`. The per-element check that detects `dataclasses.asdict`/`astuple` recursion now reads `frame.f_code.co_filename` directly instead of calling `inspect.getfile()`, cutting proxy read overhead by roughly 3-4x on large containers without changing behavior. ([#6600](https://github.com/reflex-dev/reflex/issues/6600))

### Miscellaneous

- Report the versions of the first-party Reflex subpackages shipped with Reflex (`reflex-base`, the `reflex-components-*` family and `reflex-hosting-cli`) in anonymous telemetry via a new `reflex_package_version` field. The set is derived from Reflex's own declared dependencies, so unrelated third-party `reflex-*` packages are never reported. Now that Reflex is split across many independently-versioned packages, the single `reflex_version` field no longer reflects the full install. ([#6610](https://github.com/reflex-dev/reflex/issues/6610))


## v0.9.4 (2026-06-03)

### Deprecations
Expand Down
1 change: 0 additions & 1 deletion news/6301.feature.md

This file was deleted.

1 change: 0 additions & 1 deletion news/6447.feature.md

This file was deleted.

1 change: 0 additions & 1 deletion news/6600.performance.md

This file was deleted.

1 change: 0 additions & 1 deletion news/6610.misc.md

This file was deleted.

1 change: 0 additions & 1 deletion news/6611.bugfix.md

This file was deleted.

1 change: 0 additions & 1 deletion news/6614.bugfix.md

This file was deleted.

1 change: 0 additions & 1 deletion news/6630.feature.md

This file was deleted.

1 change: 0 additions & 1 deletion news/6633.bugfix.md

This file was deleted.

1 change: 0 additions & 1 deletion news/6639.feature.md

This file was deleted.

21 changes: 21 additions & 0 deletions packages/reflex-base/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
## v0.9.5 (2026-06-10)

### Features

- Event-argument type checking now treats a mapping-style payload as compatible with a `TypedDict`-annotated callback parameter, scoped narrowly to `on_submit` triggers whose payload is a `Mapping[str, ...]` so unrelated mapping events are unaffected. Adds the `FORM_SUBMIT_MAPPING` type var (exposed on the event namespace and `pyi_generator`'s default imports) and a `Component._is_form_control` class marker that a component sets to declare it contributes a named field to form submission data. ([#6301](https://github.com/reflex-dev/reflex/issues/6301))
- `VarData` gained an `app_wraps` field so a `Var` can declare the app-level wrapper components it requires; the compiler injects them around the app root, deduped by `(priority, tag)`. This is how the state and event-loop providers now reach the React tree, since event dispatch reaches `addEvents` via a module-level import (`Imports.EVENTS`) rather than a hoisted hook. The still-reactive `connectErrors` value moves to its own `CONNECT_ERRORS` import/hook, and `Component` deep copies now drop the render cache so compile-time clones (e.g. the app-root wrapper chain) render their mutated children. ([#6447](https://github.com/reflex-dev/reflex/issues/6447))
- Added a `hydrate_fallback` config option (settable via the `REFLEX_HYDRATE_FALLBACK` environment variable), a dotted import path to a callable returning the component shown while the page is hydrating. The app root template now emits a React Router `HydrateFallback` export when a fallback is provided, and the import-path resolution shared with `extra_overlay_function` resolves nested module paths correctly. ([#6630](https://github.com/reflex-dev/reflex/issues/6630))
- Added the `REFLEX_HOT_RELOAD_OVERRIDE_PATHS` environment variable, a colon-separated list of paths that, when set, fully replaces the paths watched for hot reload in dev mode. ([#6639](https://github.com/reflex-dev/reflex/issues/6639))

### Bug Fixes

- The `reflex_base.utils.pyi_generator` build-hook entrypoint no longer rewrites `pyi_hashes.json`: it only emits the `.pyi` stubs bundled in the wheel, so building a component package (or the build triggered by `uv sync`) no longer wipes the hash registry down to a single package's entries. The scanner also tolerates source-less modules (e.g. an empty `__init__.py`) instead of raising `OSError` on Python < 3.13. ([#6614](https://github.com/reflex-dev/reflex/issues/6614))
- Fixed `State.router.url` reflecting a stale query string after the URL was changed with `window.history.replaceState`/`pushState` (e.g. from `rx.call_script`). React Router's location does not observe direct history manipulation, so the query and hash are now read from the live `window.location` when building `router_data`, and the next event sent to the backend reports the correct URL (the path stays basename-relative so `frontend_path` is not applied twice; embedded apps keep using the in-widget memory router). A direct history mutation is intentionally not a navigation and does not itself emit an event — use `rx.redirect(..., replace=True)` when you need the URL change to update the router reactively and trigger `on_load`. ([#6625](https://github.com/reflex-dev/reflex/issues/6625))
- pyi_generator no longer includes underscore-prefixed props in generated .pyi files. ([#6628](https://github.com/reflex-dev/reflex/issues/6628))
- Frontend-only events (e.g. `rx.toast`, `rx.redirect`) returned from a middleware's `preprocess` are now emitted to the client instead of being enqueued on the backend event queue, where they had no registered handler and raised `KeyError`. The frontend/backend split that already applied to handler-yielded events is now shared via a `_route_events` helper and applied to middleware-preprocess updates too. ([#6644](https://github.com/reflex-dev/reflex/issues/6644))

### Performance

- Speed up component creation by resolving field defaults lazily (via class-level descriptors) instead of eagerly on every instance, caching each component class's event triggers, and memoizing `to_camel_case`. ([#6576](https://github.com/reflex-dev/reflex/issues/6576))


## v0.9.4 (2026-06-03)

### Deprecations
Expand Down
1 change: 0 additions & 1 deletion packages/reflex-base/news/6301.feature.md

This file was deleted.

1 change: 0 additions & 1 deletion packages/reflex-base/news/6447.feature.md

This file was deleted.

1 change: 0 additions & 1 deletion packages/reflex-base/news/6576.performance.md

This file was deleted.

1 change: 0 additions & 1 deletion packages/reflex-base/news/6614.bugfix.md

This file was deleted.

1 change: 0 additions & 1 deletion packages/reflex-base/news/6625.bugfix.md

This file was deleted.

1 change: 0 additions & 1 deletion packages/reflex-base/news/6628.bugfix.md

This file was deleted.

1 change: 0 additions & 1 deletion packages/reflex-base/news/6630.feature.md

This file was deleted.

1 change: 0 additions & 1 deletion packages/reflex-base/news/6639.feature.md

This file was deleted.

1 change: 0 additions & 1 deletion packages/reflex-base/news/6644.bugfix.md

This file was deleted.

5 changes: 5 additions & 0 deletions packages/reflex-components-lucide/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## v1.0.2 (2026-06-10)

### Bug Fixes

- `rx.icon` with a static name now emits a deep per-icon import (`import LucideWifiOff from "lucide-react/dist/esm/icons/wifi-off.mjs"`) instead of a named import from the `lucide-react` barrel. The barrel import was harmless on its own, but once an app's module graph also contained `lucide-react/dynamic.mjs` (pulled in by dynamic `Var`-tagged icons, and by the connection overlay mounted on every page), esbuild's dev dep-optimizer rewrote the barrel to statically import every icon chunk — making each page load fetch the entire ~1700-icon library. Deep imports load only the icons actually used. The dynamic `Var` path still resolves through `lucide-react/dynamic.mjs` and is unchanged. ([#6628](https://github.com/reflex-dev/reflex/issues/6628))
1 change: 0 additions & 1 deletion packages/reflex-components-lucide/news/6628.bugfix.md

This file was deleted.

Loading