Style with CSS and Tailwind, component by component.
Style individual components, reuse CSS and Tailwind styles, and compose responsive layouts. Build a branded workspace around the analysis.
Explore responsive stylingBuild a custom application around the Python logic you already trust. Control your interface, navigation, and interactions with a React frontend generated from Python, without hand-writing a separate React app. Deploy with Reflex or on your own infrastructure.
Reflex is a Python alternative to Streamlit for teams taking an app to production. Updated September 2026.
When your Streamlit dashboard becomes a daily workflow, take control of the screens, components, and interactions around it.
Style individual components, reuse CSS and Tailwind styles, and compose responsive layouts. Build a branded workspace around the analysis.
Explore responsive stylingExtend the interface with React libraries or custom components. Connect their props and events to your Python application.
Explore React componentsModel drafts, saves, and background work with explicit Python state and event handlers. Give each action a clear place in your application.
Explore Python eventsBring your data, record details, and decisions into one workspace.
From e-commerce analytics to cybersecurity and internal tools, hear why these teams chose Reflex for their next application.
“With Reflex the code is much more organized and every time the user does something it's more dynamic, more event based.”
In an internal NBA dashboard benchmark, the Reflex implementation showed the player table in 2.1 seconds on simulated slow 4G. The Streamlit implementation took 15.6 seconds.
NBA dashboard · Simulated slow 4G
Lower is better.
| Network | Reflex | Streamlit |
|---|---|---|
| Local | 436 ms | 681 ms |
| Cable | 484 ms | 1,727 ms |
| Simulated slow 4G | 2,132 ms | 15,556 ms |
Source: NBA Data App, Production Performance, June 3, 2026. Production-mode apps on one Linux workstation, measured in Chromium with a cold browser cache. Values are medians of 7 local, 5 cable, and 3 slow-4G runs. Cable: 20/5 Mbps and 28 ms RTT. Slow 4G: 1.6/0.75 Mbps, 150 ms RTT, and 4x CPU slowdown. Time to visible data is the later of first contentful paint and table rows entering the DOM.
These supplied results have not been independently reproduced. Caveats:
Results depend on the implementation and environment.
See how each framework approaches custom interfaces, application state, and deployment.
Scroll horizontally to compare both products.
Scroll horizontally to compare →
| Decision | Streamlit | Reflex |
|---|---|---|
| Styling and layout | Configure app themes and use layout primitives to organize widgets. | Control CSS at component and global levels. Compose reusable styles and responsive layouts around your workflow. |
| Custom components | Extend the UI with custom components; Components v2 can integrate directly into the page. | Wrap React libraries or local React components, exposing props and events to your Python application. |
| Interactions and state | Uses a script rerun model with session state. Forms batch inputs and fragments can rerun independently. | Model user actions with Python event handlers and explicit state. Connect draft edits, saves, and background work to your UI. |
| Python and the frontend | Author data apps with Python scripts and Streamlit UI commands. | Author the interface and application logic in Python. Reflex compiles the interface to React and runs backend logic in Python. |
| Deployment | Deploy through Streamlit Community Cloud or other hosting providers. | Choose managed Reflex hosting or self-host the frontend and Python backend on infrastructure you control. |
Compare how Streamlit and Reflex handle styling, components, interactions, and deployment. The NBA performance example on this page measures one implementation of each framework.
Build a React-powered interface while continuing to author your application in Python.
Reflex generates a React frontend from an interface authored in Python. Keep independent calculations, data clients, and Python libraries without maintaining a separate handwritten React application. Specialized components may still need JavaScript or TypeScript.
Migration is a deliberate interface rebuild. Reuse independent Python logic while adapting Streamlit widgets, session state, caching, and rerun-dependent code to the new application.
How Reflex generates your frontendStart with a working slice of your Streamlit app. Preserve the result, improve the experience, and validate it with real users.
Choose one calculation and a fixed dataset. Record the current results and extract reusable Python logic from the Streamlit UI.
Compose a queue, record details, and an edit form in Reflex. Map session state and rerun-dependent behavior to explicit events.
Implement authorization and persistent saves. Check invalid input, failed requests, duplicate submissions, and recovery after reload.
Compare results with the baseline. Test realistic network and concurrency conditions, then deploy with Reflex or self-host.
Move an approval action from session state into a typed Reflex State. The button still calls Python; Reflex updates the interface from the changed state.
import streamlit as st
if "approved" not in st.session_state:
st.session_state.approved = False
def approve():
st.session_state.approved = True
st.button("Approve", on_click=approve)
st.write("Approved" if st.session_state.approved else "Pending")import reflex as rx
class ApprovalState(rx.State):
approved: bool = False
@rx.event
def approve(self):
self.approved = True
def index():
return rx.vstack(
rx.button("Approve", on_click=ApprovalState.approve),
rx.text(rx.cond(ApprovalState.approved, "Approved", "Pending")),
)
app = rx.App()
app.add_page(index)These minimal examples keep approval in session state. A production workflow also needs server-side authorization, database persistence, and error handling.
Use managed Reflex hosting or run the frontend and Python backend on your own infrastructure. Plan authentication, authorization, monitoring, and capacity for your application.
The Apache 2.0 Python framework is available independently of Build and managed hosting. Your app still depends on Reflex and its other packages.
The AI development product generates and edits framework-based apps. Usage, private projects, repository access, and export entitlements belong to your plan.
Managed deployment is an operating service. You can also self-host a framework app, providing its frontend, Python backend, configuration, and maintenance.
Enterprise packages and services have separate entitlements. Workspace SSO is distinct from app-user authentication. Authorization, auditing, and private deployment need configuration and an agreed operating plan.
Production, performance, and what changes when you migrate.
Streamlit supports deployed applications. Production readiness depends on your app’s access controls, reliability, performance, and operating requirements. Choose Reflex when you want direct control over a custom interface, navigation, and application workflows while keeping your team in Python.
Streamlit uses a script rerun model, with session state carrying values between runs. Forms batch inputs and fragments limit reruns to part of the app. As workflows span multiple pages, background jobs, and per-user access rules, developers must coordinate state, job lifecycles, and authorization across those execution paths. Reflex models user actions with explicit Python event handlers tied to typed state, giving draft edits, saves, and background work their own place in the application. Authorization still needs to be implemented in either framework.
With Reflex, you author the interface in Python and Reflex generates React. You still rebuild the Streamlit UI and adapt its interactions and state. You do not need a separate handwritten React application; specialized custom components may require JavaScript or TypeScript.
Independent calculations, data clients, models, and Python libraries are candidates for reuse. Separate them from Streamlit UI calls, caching, and session state, then validate their outputs when called from Reflex event handlers.
Style individual components with CSS, reuse styles, and build responsive layouts with grid and flex. Add dynamic routes and wrap React libraries when you need specialized components. Streamlit also supports theming and custom components; Reflex makes whole-application composition part of its Python model.
Measure your workload. The NBA example on this page shows lower time to visible data for one optimized Reflex implementation. It does not establish faster interactions or greater capacity for every app. Profile data access, rendering, network conditions, and concurrency before and after migration.
Bring a workflow you want to improve. Build the next version with Reflex.