Here is a quick guide on how to run Reflex repo locally so you can start contributing to the project.
Prerequisites:
- uv version >= 0.9.17 and add it to your path (see UV Docs for more info).
1. Fork this repository:
Fork this repository by clicking on the Fork button on the top right.
2. Clone Reflex and navigate into the repo:
git clone https://github.com/<YOUR-USERNAME>/reflex.git
cd reflex3. Install your local Reflex build:
uv sync4. Now create an examples folder so you can test the local Python build in this repository.
- We have the
examplesfolder in the.gitignore, so your changes inreflex/exampleswon't be reflected in your commit.
mkdir examples
cd examples5. Init and Run
uv run reflex init
uv run reflex runAll the changes you make to the repository will be reflected in your running app.
- We have the examples folder in the .gitignore, so your changes in reflex/examples won't be reflected in your commit.
Any feature or significant change added should be accompanied with unit tests.
Within the 'test' directory of Reflex you can add to a test file already there or create a new test python file if it doesn't fit into the existing layout.
- Any feature or significant change that has been added.
- Any edge cases or potential problem areas.
- Any interactions between different parts of the code.
Each PR that changes the source of a published package must add a news fragment describing the change. Fragments are assembled into CHANGELOG.md at release time by towncrier.
Where: add the fragment under the affected package's news/ directory. For the main reflex package, that's the repo-root news/. For sub-packages it's packages/<name>/news/.
Filename: <pr-or-issue-number>.<type>.md, where <type> is one of:
| Type | When to use |
|---|---|
breaking |
Backwards-incompatible change users need to adapt to |
deprecation |
API marked deprecated but still functional |
feature |
New user-facing functionality |
bugfix |
Fix for an incorrect behavior |
performance |
Speed, memory, or startup improvement |
docs |
Documentation or docstring changes |
misc |
Internal refactor, build, or dependency change that still warrants mention |
Content: one or two sentences, written for users reading release notes (not reviewers of the diff).
Create a fragment from the CLI:
uv run towncrier create --config pyproject.toml --dir packages/reflex-components-lucide 1234.feature.mdDrop --dir for a fragment against the main reflex package.
If you don't yet know the PR number, use an orphan fragment (+.feature.md) and rename it after opening the PR.
Skipping the fragment check: for PRs that are genuinely not user-facing (CI-only tweaks, script fixes, test-only changes), apply the skip-changelog label on the PR to bypass the changelog CI check.
Changelog version headings: PRs to main must not add new version headings to any CHANGELOG.md β a merged heading without a git tag is a publish trigger, so new headings only come from the Dispatch release workflow. CI enforces this with the same parser the release pipeline uses; for deliberate restructuring of already-published sections, apply the changelog-version-edit label.
Releasing (maintainers): the CHANGELOG.md files are the source of truth
for publishing. A release is cut by materializing the news fragments into a
package's CHANGELOG.md under a new version heading and landing that change on
a release branch β never by tagging manually. The pieces:
- Dispatch release (
dispatch_release.yml, run from the Actions tab) selects packages and a release action, computes the next version(s), runs towncrier, and delivers the changelog bump. Leaving every package unchecked auto-selects the packages with pending news fragments (forrelease-from-prerelease: the packages whose changelog is topped by an alpha). Details:- Prerelease actions (
new-prerelease-*,continued-prerelease) push alpha versions straight to anr/pre-<date>branch (continued prereleases push back to ther/pre-*branch they are dispatched on); alphas build immediately and upload once thepypienvironment deployment is approved. To pull new work into a prerelease train, mergemaininto its branch and dispatchcontinued-prereleaseon it. - Release actions (
release-*) open a PR with the changelog changes instead; reviewing and merging that PR is how final versions land (the upload still waits for thepypienvironment approval below). The PR targetsmain, or ther/hotfix/...branch the workflow was dispatched on (hotfix branches may publish final versions directly).release-from-prereleasecollapses the accumulated alpha sections into one final-version section β alpha headings never ship in a final changelog. - Selecting
reflex-baseautomatically releases the rootreflexpackage at the same version.
- Prerelease actions (
- Release from changelog (
release_from_changelog.yml) runs on every push tomain,r/pre-*, andr/hotfix/**: any package whose newest changelog version has no git tag gets built and queued for publishing. Final (non-alpha) versions only publish frommainorr/hotfix/**; alphas only fromr/pre-*/r/hotfix/**.reflexandreflex-baseare checked as a lockstep pair andreflexpublishes only after the rest of the batch. - Publish to PyPI (
publish.yml, also manually dispatchable with a package + version) validates and builds without privileges, then waits for a human to approve thepypienvironment deployment β every upload, alphas and internal packages included, requires that approval. Only after a successful upload does it push the tag and create the GitHub release, so a failed or rejected publish leaves no tag behind β fix the problem on top of the changelog bump and the next push retries automatically.
Where changelogs are published: the docs site renders every CHANGELOG.md
in the repo (repo root and packages/*/) under
reflex.dev/docs/changelog/. The
reflex-enterprise changelog is read from the installed reflex-enterprise
distribution at docs build time; it appears once the published wheel ships a
CHANGELOG.md and the docs app's lockfile picks up that version.
Once you solve a current issue or improvement to Reflex, you can make a PR, and we will review the changes.
Before submitting, a pull request, ensure the following steps are taken and test passing.
In your reflex directory run make sure all the unit tests are still passing using the following command.
This will fail if code coverage is below 72%.
uv run pytest tests/units --cov --no-cov-on-fail --cov-report=Next make sure all the following tests pass. This ensures that every new change has proper type checking.
uv run ruff check .
uv run pyright reflex testsFinally, run ruff to format your code.
uv run ruff format .Consider installing git pre-commit hooks so Ruff, Pyright, and make_pyi will run automatically before each commit.
uv run pre-commit installThat's it you can now submit your PR. Thanks for contributing to Reflex!
We welcome AI-assisted contributions, but they must meet the same quality bar as any other PR.
- A human developer must be responsible for the PR contents and review process. Bot account PRs are subject to prejudicial closure.
- Ensure pre-commit hooks and unit tests pass before submitting.
- Review the patch locally with an "adversarial" prompt before opening the PR.
- Apply fixes for reasonable feedback from Greptile and/or Copilot review bots.
- Resolve or dismiss irrelevant bot feedback with a brief explanation.
- All added/changed lines MUST have unit or integration test coverage with real assertions. No untested code, no bogus test code.
- PRs with merge conflicts or failing tests will not be reviewed or merged. The maintainers do not spend time on PRs that are not in a ready state. If you need attention on a PR that is not ready, mention the maintainers in a comment.
The Reflex documentation lives in this repo under docs/. All doc pages are plain Markdown files in docs/, and the docs site itself (a Reflex app that renders them) lives in docs/app/. If you're fixing a typo, clarifying an explanation, or adding a new page, you can do it all in this repo by editing the relevant .md file.
1. Run the docs site locally:
cd docs/app
uv sync
uv run reflex runThen open http://localhost:3000/docs/. The dev server picks up changes to the .md files in docs/ so you can preview edits live.
2. Speed up dev builds with the page whitelist (optional):
By default the dev server compiles every page, which can be slow. To only compile the pages you're working on, edit docs/app/reflex_docs/whitelist.py and add paths to WHITELISTED_PAGES:
WHITELISTED_PAGES = [
"/getting-started/introduction",
"/components/props",
]Paths must start with /, have no trailing slash, and are prefix-matched. An empty list builds everything. Restart the dev server after editing.
Changes to the basic blank template can be done in the reflex/.templates/apps/blank directory.
For some pull requests when adding new components you will have to generate a pyi file for the new component. This is done by running the following command in the reflex directory.
(Please check in with the team before adding a new component to Reflex we are cautious about adding new components to Reflex's core.)
uv run python -m reflex.utils.pyi_generator