Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
2656ee5
feat: Add explicit state ID minification for states
benedikt-bartscher Jan 24, 2026
1c5114d
drop uploaded_files, don't allow state_id for mixins
benedikt-bartscher Jan 24, 2026
62bf127
Update reflex/state.py
benedikt-bartscher Jan 24, 2026
0858c9e
ruffing
benedikt-bartscher Jan 24, 2026
be13be5
minify event names as well
benedikt-bartscher Jan 24, 2026
e53c76a
wip fixing minifed state names + add cli
benedikt-bartscher Jan 24, 2026
fc4c5e1
wip cli
benedikt-bartscher Jan 25, 2026
6d13bec
wtf prettier
benedikt-bartscher Jan 25, 2026
b2c3f58
Merge remote-tracking branch 'upstream' into explicit-event-id-minifi…
benedikt-bartscher Jan 27, 2026
f2f1ac7
Merge remote-tracking branch 'upstream' into explicit-event-id-minifi…
benedikt-bartscher Jan 28, 2026
db97e3a
update pyi_hashes
benedikt-bartscher Jan 28, 2026
6b4c5fa
unique per sibling
benedikt-bartscher Jan 28, 2026
a230be2
Merge remote-tracking branch 'upstream/main' into explicit-event-id-m…
benedikt-bartscher Feb 1, 2026
1647c1e
fix test state ids
benedikt-bartscher Feb 1, 2026
e375b7e
add best-effort mode for event ids
benedikt-bartscher Feb 1, 2026
a94c98b
minify json poc
benedikt-bartscher Feb 1, 2026
ee4c7f1
fix codespell
benedikt-bartscher Feb 1, 2026
bcc4b49
add support for dynamic event handlers, streamline event handler form…
benedikt-bartscher Feb 1, 2026
fc787e6
forgot to remove this state prefix
benedikt-bartscher Feb 1, 2026
5b6e124
more streamline with format event handler
benedikt-bartscher Feb 1, 2026
ae477ae
allow to enable/disable state and event ID minification independently…
benedikt-bartscher Feb 4, 2026
e13073b
fix: prevent parent-child minified name collision in substate resolution
benedikt-bartscher Feb 4, 2026
d669571
fix: consistent plural naming for state minification env vars
benedikt-bartscher Feb 4, 2026
ed085c0
make integration tests use our typed env helpers
benedikt-bartscher Feb 4, 2026
b2c2ff0
prefer assert isinstance over cast.
benedikt-bartscher Feb 4, 2026
8f44d49
drop old state_id parameter from BaseStateMeta
benedikt-bartscher Feb 4, 2026
cf7b614
fix: drop unused EVENT_ID_MARKER constant
benedikt-bartscher Feb 4, 2026
3074c84
fix: correctly count events in minification cli
benedikt-bartscher Feb 4, 2026
ca73b45
fix: adjust minify lookup cli for new minify.json, add tests
benedikt-bartscher Feb 6, 2026
d5f159c
fix: reflex minify validate - warn and exit 1 if missing entries
benedikt-bartscher Feb 6, 2026
f964c7a
fix: use get_event_handler in upload
benedikt-bartscher Feb 7, 2026
1aac145
Merge remote-tracking branch 'upstream' into explicit-event-id-minifi…
benedikt-bartscher Feb 12, 2026
019e6f3
fix: avoid assertion in runtime, prefer raising TypeError
benedikt-bartscher Feb 12, 2026
5f57707
Merge remote-tracking branch 'upstream/main' into explicit-event-id-m…
benedikt-bartscher Feb 13, 2026
dbb1fb6
Merge remote-tracking branch 'upstream/main' into explicit-event-id-m…
benedikt-bartscher Feb 14, 2026
e713b5b
Merge remote-tracking branch 'upstream/main' into explicit-event-id-m…
benedikt-bartscher Feb 24, 2026
e2ca73e
bump packaging upper-bound to <27 (#6102)
masenf Jan 27, 2026
9201f0e
Bump python-multipart in the uv group across 1 directory (#6103)
dependabot[bot] Jan 27, 2026
f2e4e5a
fix: Preserve event_actions from @rx.event decorator in mixin event h…
benedikt-bartscher Jan 27, 2026
e2e6d14
Fix socket reference shape mismatch in queueEvents (#6094)
Dadzemovic Jan 27, 2026
b132303
fix: Preserve object identity when pickling MutableProxy (#6097)
benedikt-bartscher Jan 28, 2026
413901b
fix: Copy ID even when it is a var. (#6105)
abulvenz Jan 29, 2026
8d9ed97
Origin/matthew collins nz/adddataeditorrowcheckboxvisible (#6082)
MatthewCollinsNZ Feb 12, 2026
29965cf
Catch all exceptions in health checks (#6089)
masenf Feb 12, 2026
73901cd
Run external servers with `sys.executable -m` (#6095)
masenf Feb 12, 2026
3934bc4
Use homogenous tuple annotation in BaseStateMeta.__new__ (#6096)
masenf Feb 12, 2026
087c024
adding row selection mode (#6090)
MatthewCollinsNZ Feb 12, 2026
0580d84
use get_event_handler in upload, cherry-pick from #6100 (#6130)
benedikt-bartscher Feb 12, 2026
7405808
Data editor search props (#6113)
MatthewCollinsNZ Feb 12, 2026
7c0b6c2
Bump pillow from 12.1.0 to 12.1.1 in the uv group across 1 directory …
dependabot[bot] Feb 12, 2026
64da061
Allow granian log level to be set (#6131)
masenf Feb 12, 2026
63121f6
cache get_type_hints for heavy init subclass stuff - improve import p…
benedikt-bartscher Feb 13, 2026
c8c2ab1
0828dev (#6136)
adhami3310 Feb 23, 2026
ca28a6e
Unlink broken symlinks in the assets folder (#6140)
masenf Mar 5, 2026
5cd8397
feat: add vite_allowed_hosts config option for Vite dev server (#6147)
milochen0418 Mar 6, 2026
129b904
fix: include frontend_path in sirv prod command for correct 404.html …
masenf Mar 6, 2026
b89c80b
fix: make disable_plugins accept Plugin types instead of strings (#6155)
masenf Mar 6, 2026
5716a9e
bump devcontainer to python:3.14-trixie (#6158)
masenf Mar 6, 2026
9bd6ad1
Merge branch 'main', remote-tracking branch 'upstream' into explicit-…
benedikt-bartscher Mar 12, 2026
e8b5724
fix: use actual parent class for sibling grouping in minify sync/vali…
benedikt-bartscher Mar 12, 2026
30bf7a3
Merge remote-tracking branch 'upstream/main' into explicit-event-id-m…
benedikt-bartscher Mar 23, 2026
43815c0
Merge remote-tracking branch 'upstream' into explicit-event-id-minifi…
benedikt-bartscher Mar 26, 2026
10434bd
Merge remote-tracking branch 'upstream/main' into explicit-event-id-m…
benedikt-bartscher Apr 25, 2026
9e73376
ruff format
benedikt-bartscher Apr 25, 2026
79b735d
pre-commit
benedikt-bartscher Apr 25, 2026
052beca
test adjustments
benedikt-bartscher Apr 25, 2026
1cc98a8
migrate minify to registry name resolver
benedikt-bartscher Apr 25, 2026
bd63210
pre-commit
benedikt-bartscher Apr 25, 2026
5ad6e3e
add support for dynamic states in minification
benedikt-bartscher Apr 25, 2026
66dcbe5
cleanup
benedikt-bartscher Apr 25, 2026
673243c
wip
benedikt-bartscher Apr 26, 2026
6cdf383
cleanup
benedikt-bartscher Apr 26, 2026
050727a
dry it up
benedikt-bartscher Apr 26, 2026
de1804a
dry up the tests
benedikt-bartscher Apr 26, 2026
c99b450
typing improvements and cleanup
benedikt-bartscher Apr 26, 2026
05fde77
cleanup
benedikt-bartscher Apr 26, 2026
9b57ec1
wip
benedikt-bartscher Apr 26, 2026
fc0ba15
Merge remote-tracking branch 'upstream/main' into explicit-event-id-m…
benedikt-bartscher Apr 28, 2026
b0983ed
Merge remote-tracking branch 'upstream/main' into explicit-event-id-m…
benedikt-bartscher May 6, 2026
bc3890a
try to improve benchmark
benedikt-bartscher May 6, 2026
aa32843
cache event handler names
benedikt-bartscher May 6, 2026
f83afad
Merge remote-tracking branch 'upstream/main' into explicit-event-id-m…
benedikt-bartscher Jul 9, 2026
228b8ed
fix: record parent path in minify.json state entries so orphaned ids …
benedikt-bartscher Jul 9, 2026
af4219f
fix codespell
benedikt-bartscher Jul 9, 2026
d378a59
Merge remote-tracking branch 'upstream/main' into explicit-event-id-m…
benedikt-bartscher Jul 17, 2026
c5cceb6
fix: prevent state definition before minify is active
benedikt-bartscher Jul 20, 2026
1bafa2d
fix ruff
benedikt-bartscher Jul 20, 2026
c3e0f1c
greptile
benedikt-bartscher Jul 20, 2026
44fefa1
cleanup
benedikt-bartscher Jul 20, 2026
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ reflex.db
node_modules
package-lock.json
*.pyi
.pre-commit-config.yaml
.pre-commit-config.yaml
uploaded_files/*
13 changes: 7 additions & 6 deletions reflex/.templates/web/utils/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import {
onLoadInternalEvent,
state_name,
exception_state_name,
main_state_name,
update_vars_internal,
} from "$/utils/context";
import debounce from "$/utils/helpers/debounce";
import throttle from "$/utils/helpers/throttle";
Expand Down Expand Up @@ -134,7 +136,7 @@ export const isStateful = () => {
if (event_queue.length === 0) {
return false;
}
return event_queue.some((event) => event.name.startsWith("reflex___state"));
return event_queue.some((event) => event.name.startsWith(main_state_name));
};

/**
Expand Down Expand Up @@ -1034,10 +1036,9 @@ export const useEventLoop = (
if (storage_to_state_map[e.key]) {
const vars = {};
vars[storage_to_state_map[e.key]] = e.newValue;
const event = ReflexEvent(
`${state_name}.reflex___state____update_vars_internal_state.update_vars_internal`,
{ vars: vars },
);
const event = ReflexEvent(`${state_name}.${update_vars_internal}`, {
vars: vars,
});
addEvents([event], e);
}
};
Expand Down Expand Up @@ -1072,7 +1073,7 @@ export const useEventLoop = (
}

// Equivalent to routeChangeStart - runs when navigation begins
const main_state_dispatch = dispatch["reflex___state____state"];
const main_state_dispatch = dispatch[main_state_name];
if (main_state_dispatch !== undefined) {
main_state_dispatch({ is_hydrated_rx_state_: false });
}
Expand Down
28 changes: 25 additions & 3 deletions reflex/compiler/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,20 @@ def context_template(
Returns:
Rendered context file content as string.
"""
# Import state classes to get dynamic names (supports minification)
from reflex.state import (
FrontendEventExceptionState,
OnLoadInternalState,
State,
UpdateVarsInternalState,
)

# Compute dynamic state names that respect minification settings
main_state_name = State.get_name()
on_load_internal = f"{OnLoadInternalState.get_name()}.on_load_internal"
update_vars_internal = f"{UpdateVarsInternalState.get_name()}.update_vars_internal"
exception_state_full = FrontendEventExceptionState.get_full_name()

initial_state = initial_state or {}
state_contexts_str = "".join([
f"{format_state_name(state_name)}: createContext(null),"
Expand All @@ -284,7 +298,11 @@ def context_template(
rf"""
export const state_name = "{state_name}"

export const exception_state_name = "{constants.CompileVars.FRONTEND_EXCEPTION_STATE_FULL}"
export const main_state_name = "{main_state_name}"

export const update_vars_internal = "{update_vars_internal}"

export const exception_state_name = "{exception_state_full}"

// These events are triggered on initial load and each page navigation.
export const onLoadInternalEvent = () => {{
Expand All @@ -296,15 +314,15 @@ def context_template(
if (client_storage_vars && Object.keys(client_storage_vars).length !== 0) {{
internal_events.push(
ReflexEvent(
'{state_name}.{constants.CompileVars.UPDATE_VARS_INTERNAL}',
'{state_name}.{update_vars_internal}',
{{vars: client_storage_vars}},
),
);
}}

// `on_load_internal` triggers the correct on_load event(s) for the current page.
// If the page does not define any on_load event, this will just set `is_hydrated = true`.
internal_events.push(ReflexEvent('{state_name}.{constants.CompileVars.ON_LOAD_INTERNAL}'));
internal_events.push(ReflexEvent('{state_name}.{on_load_internal}'));

return internal_events;
}}
Expand All @@ -319,6 +337,10 @@ def context_template(
else """
export const state_name = undefined

export const main_state_name = undefined

export const update_vars_internal = undefined

export const exception_state_name = undefined

export const onLoadInternalEvent = () => []
Expand Down
12 changes: 0 additions & 12 deletions reflex/constants/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,6 @@ class CompileVars(SimpleNamespace):
CONNECT_ERROR = "connectErrors"
# The name of the function for converting a dict to an event.
TO_EVENT = "ReflexEvent"
# The name of the internal on_load event.
ON_LOAD_INTERNAL = "reflex___state____on_load_internal_state.on_load_internal"
# The name of the internal event to update generic state vars.
UPDATE_VARS_INTERNAL = (
"reflex___state____update_vars_internal_state.update_vars_internal"
)
# The name of the frontend event exception state
FRONTEND_EXCEPTION_STATE = "reflex___state____frontend_event_exception_state"
# The full name of the frontend exception state
FRONTEND_EXCEPTION_STATE_FULL = (
f"reflex___state____state.{FRONTEND_EXCEPTION_STATE}"
)


class PageNames(SimpleNamespace):
Expand Down
15 changes: 15 additions & 0 deletions reflex/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,15 @@ class PerformanceMode(enum.Enum):
OFF = "off"


@enum.unique
class MinifyMode(enum.Enum):
"""Mode for state/event name minification."""

DISABLED = "disabled" # Never minify names (default)
ENABLED = "enabled" # Minify items that have explicit IDs
ENFORCE = "enforce" # Require all items to have explicit IDs


class ExecutorType(enum.Enum):
"""Executor for compiling the frontend."""

Expand Down Expand Up @@ -688,6 +697,12 @@ class EnvironmentVariables:
# The maximum size of the reflex state in kilobytes.
REFLEX_STATE_SIZE_LIMIT: EnvVar[int] = env_var(1000)

# State name minification mode: disabled, enabled, or enforce.
REFLEX_MINIFY_STATES: EnvVar[MinifyMode] = env_var(MinifyMode.DISABLED)

# Event handler name minification mode: disabled, enabled, or enforce.
REFLEX_MINIFY_EVENTS: EnvVar[MinifyMode] = env_var(MinifyMode.DISABLED)

# Whether to use the turbopack bundler.
REFLEX_USE_TURBOPACK: EnvVar[bool] = env_var(False)

Expand Down
9 changes: 9 additions & 0 deletions reflex/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ def substate_token(self) -> str:
_EVENT_FIELDS: set[str] = {f.name for f in dataclasses.fields(Event)}

BACKGROUND_TASK_MARKER = "_reflex_background_task"
EVENT_ID_MARKER = "_rx_event_id"


@dataclasses.dataclass(
Expand Down Expand Up @@ -2311,6 +2312,7 @@ class EventNamespace:

# Constants
BACKGROUND_TASK_MARKER = BACKGROUND_TASK_MARKER
EVENT_ID_MARKER = EVENT_ID_MARKER
_EVENT_FIELDS = _EVENT_FIELDS
FORM_DATA = FORM_DATA
upload_files = upload_files
Expand All @@ -2334,6 +2336,7 @@ def __new__(
throttle: int | None = None,
debounce: int | None = None,
temporal: bool | None = None,
event_id: int | None = None,
) -> Callable[
[Callable[[BASE_STATE, Unpack[P]], Any]], EventCallback[Unpack[P]] # pyright: ignore [reportInvalidTypeVarUse]
]: ...
Expand All @@ -2349,6 +2352,7 @@ def __new__(
throttle: int | None = None,
debounce: int | None = None,
temporal: bool | None = None,
event_id: int | None = None,
) -> EventCallback[Unpack[P]]: ...

def __new__(
Expand All @@ -2361,6 +2365,7 @@ def __new__(
throttle: int | None = None,
debounce: int | None = None,
temporal: bool | None = None,
event_id: int | None = None,
) -> (
EventCallback[Unpack[P]]
| Callable[[Callable[[BASE_STATE, Unpack[P]], Any]], EventCallback[Unpack[P]]]
Expand All @@ -2375,6 +2380,7 @@ def __new__(
throttle: Throttle the event handler to limit calls (in milliseconds).
debounce: Debounce the event handler to delay calls (in milliseconds).
temporal: Whether the event should be dropped when the backend is down.
event_id: Optional integer ID for deterministic minified event names.

Raises:
TypeError: If background is True and the function is not a coroutine or async generator. # noqa: DAR402
Expand Down Expand Up @@ -2462,6 +2468,9 @@ def wrapper(
event_actions = _build_event_actions()
if event_actions:
func._rx_event_actions = event_actions # pyright: ignore [reportFunctionMemberAccess]
# Store event_id on the function for minification
if event_id is not None:
setattr(func, EVENT_ID_MARKER, event_id)
return func # pyright: ignore [reportReturnType]

if func is not None:
Expand Down
Loading
Loading