Introduction
~5 min · Reflex lets you build and deploy full-stack web apps — frontend, backend, and database — in pure Python. No JavaScript, no separate API, no context switching.
Goals
Write your entire app — frontend, backend, database — in Python. No need to learn another language.
Ship your first app in minutes. No web development experience required.
Build anything from small data apps to large multi-page websites. This entire site was built and deployed with Reflex.
One tool covers it all: UI, server-side logic, and deployment.
Build a counter
We'll build a counter app that lets the user count up or down. In ~20 lines of Python you'll touch the three core pieces of every Reflex app: state, event handlers, and components.
0
Here is the full code for this example:
The frontend is built declaratively with Reflex components, which compile to JS and run in the browser. Use rx.cond and rx.foreach instead of if and for for dynamic UIs. Any non-UI logic belongs in State.
import reflex as rx class State(rx.State):
count: int = 0
@rx.event
def increment(self):
self.count += 1
@rx.event
def decrement(self):
self.count -= 1def index():
return rx.hstack(
rx.button(
"Decrement",
color_scheme="ruby",
on_click=State.decrement,
),
rx.heading(State.count, font_size="2em"),
rx.button(
"Increment",
color_scheme="grass",
on_click=State.increment,
),
spacing="4",
)app = rx.App()
app.add_page(index)The Structure of a Reflex App
Let's break this example down.
Import
Import Reflex as rx. All Reflex objects are accessed as rx.*.
State
State holds the app's mutable data. Variables declared here are called vars. Our counter has one: count, starting at 0.
Event Handlers
Event handlers are the only way to modify state. They're triggered by user actions (clicks, typing, etc.) — those actions are called events. Our counter has two handlers: increment and decrement.
User Interface (UI)
The UI is built from components (rx.hstack, rx.button, rx.heading) that can be nested and styled with CSS or Tailwind. Reflex ships with 50+ built-in components, and you can wrap any React component.
Components reference state vars (rx.heading(State.count, …)) and reactively re-render when state changes. Event triggers (on_click=State.decrement) wire UI to handlers.
The sequence goes like this:
- User clicks "Increment".
on_clickfires.State.incrementruns on the server.State.countis updated.- UI re-renders with the new value.
Add pages
Create the app and register the page at the base route.
Next Steps
🎉 You've built a fully interactive web app in pure Python.
Browse our open-source templates, or press Cmd+K / Ctrl+K to search the docs.