Skip to content

Production builds are not reproducible: every reflex export renames every script #7562

Open

Description

@H4dr1en

Describe the bug

Two reflex export --frontend-only runs of the same source produce different files: every script under assets/ gets a new name, and React Router's manifest gets a new version. So every deploy looks like a new frontend to a browser, even when only Python changed.

There are two causes:

  1. state.js imports all of .web/reflex.json (import reflexEnvironment from "$/reflex.json"), but only reads reflexEnvironment.version (the socket subprotocol). The file also holds project_hash, a random uuid written by init_reflex_json when the web folder is created, and last_reflex_run_datetime, rewritten by set_last_reflex_run_time() on every run. Both end up in the state.js chunk, so its name changes, and with it the name of every chunk that imports it.
  2. An f-string id around a Var gets a ref name that changes between runs. Var.__format__ writes <reflex.Var>{hash(var)}</reflex.Var>{js_expr} into the string, and format_ref keeps the hash digits in the ref name. The hash can include memory addresses (id()), so rx.box(id=f"zone-{item}") compiles to a different ref_..._<digits>_... name in each run.

To reproduce

for i in 1 2; do
  REFLEX_WEB_WORKDIR=/tmp/build$i reflex export --frontend-only --no-zip --env prod
done
ls /tmp/build1/build/client/assets | grep manifest
ls /tmp/build2/build/client/assets | grep manifest
diff -rq /tmp/build1/build/client /tmp/build2/build/client

Expected behavior

The same source gives the same files. Content-hashed file names only change when the content changes, which is their purpose.

Why it matters

  • Browsers re-download every script after every deploy, even when no page changed.
  • During a Kubernetes rolling update, pages and scripts come from pods with different builds even when the source is the same. A page from a new pod asks an old pod for scripts it does not have; the 404 makes React Router reload the page at once (loadRouteModule), on every deploy, including Python-only ones.
  • An app cannot tell "the frontend changed" from "the backend was redeployed" by comparing build names.

Environment

Reflex 0.10.0, and main at d02ba54. Node 24, Vite build via reflex export.

Activity

  1. linear-code commented on Oct 14, 2026

    @linear-code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions