How to build advanced multi-page Reflex web applications using a real-time database, dynamic state management, and responsive UI
In this tutorial we build a high-level reflection Web applications written entirely in Python that run seamlessly within Colab. We designed this application to demonstrate how Reflex enables full-stack development without JavaScript, using only reactive Python code. We created a complete note management dashboard with two pages, real-time database interaction, filtering, sorting, analytics and user personalization. We built the project step-by-step through five clean pieces, covering setup, configuration, model and state management, user interface design, and final execution, which allowed us to get a hands-on look at Reflex’s declarative architecture and reactive system. Check The complete code is here.
import os, subprocess, sys, pathlib
APP = "reflex_colab_advanced"
os.makedirs(APP, exist_ok=True)
os.chdir(APP)
subprocess.run([sys.executable, "-m", "pip", "install", "-q", "reflex==0.5.9"])
We set up our work environment and installed Reflex inside Colab. We create a new project directory and make sure the framework is available for use. We prepare the base environment so that our application can run smoothly later without dependency issues. Check The complete code is here.
rxconfig = """
import reflex as rx
class Config(rx.Config):
app_name = "reflex_colab_advanced"
db_url = "sqlite:///reflex.db"
config = Config()
"""
pathlib.Path("rxconfig.py").write_text(rxconfig)
We define a configuration file that specifies the application name and database connection. We connect Reflex to a local SQLite database to store our notes. We maintain this configuration as little as possible while still being critical for managing persistent data. Check The complete code is here.
app_py = """
import reflex as rx
class Note(rx.Model, table=True):
content: str
tag: str = "general"
done: bool = False
class State(rx.State):
user: str = ""
search: str = ""
tag_filter: str = "all"
sort_desc: bool = True
new_content: str = ""
new_tag: str = "general"
toast_msg: str = ""
def set_user(self, v: str): self.user = v
def set_search(self, v: str): self.search = v
def set_tag_filter(self, v: str): self.tag_filter = v
def set_new_content(self, v: str): self.new_content = v
def set_new_tag(self, v: str): self.new_tag = v
def toggle_sort(self): self.sort_desc = not self.sort_desc
async def add_note(self):
if self.new_content.strip():
await Note.create(content=self.new_content.strip(), tag=self.new_tag.strip() or "general")
self.new_content = ""; self.toast_msg = "Note added"
async def toggle_done(self, note_id: int):
note = await Note.get(id=note_id)
if note:
await note.update(done=not note.done)
async def delete_note(self, note_id: int):
await Note.delete(id=note_id)
self.toast_msg = "Deleted"
async def clear_done(self):
items = await Note.all()
for n in items:
if n.done:
await Note.delete(id=n.id)
self.toast_msg = "Cleared done notes"
async def notes_filtered(self):
items = await Note.all()
q = self.search.lower()
if q:
items = [n for n in items if q in n.content.lower() or q in n.tag.lower()]
if self.tag_filter != "all":
items = [n for n in items if n.tag == self.tag_filter]
items.sort(key=lambda n: n.id, reverse=self.sort_desc)
return items
async def stats(self):
items = await Note.all()
total = len(items)
done = len([n for n in items if n.done])
tags = {}
for n in items:
tags[n.tag] = tags.get(n.tag, 0) + 1
top_tags = sorted(tags.items(), key=lambda x: x[1], reverse=True)[:5]
return {"total": total, "done": done, "pending": total - done, "tags": top_tags}
"""
We define the data model Note and the reactive State class that controls user input, filtering, and database operations. We manage asynchronous operations such as adding, deleting, and updating notes. We also include logic to dynamically calculate statistics based on stored data. Check The complete code is here.
app_py += """
def sidebar():
return rx.vstack(
rx.heading("RC Advanced", size="6"),
rx.link("Dashboard", href="
rx.link("Notes Board", href="
rx.text("User"),
rx.input(placeholder="your name", value=State.user, on_change=State.set_user),
spacing="3", width="15rem", padding="1rem", border_right="1px solid #eee"
)
async def stats_cards():
s = await State.stats()
return rx.hstack(
rx.box(rx.text("Total"), rx.heading(str(s["total"]), size="5"), padding="1rem", border="1px solid #eee", border_radius="0.5rem"),
rx.box(rx.text("Done"), rx.heading(str(s["done"]), size="5"), padding="1rem", border="1px solid #eee", border_radius="0.5rem"),
rx.box(rx.text("Pending"), rx.heading(str(s["pending"]), size="5"), padding="1rem", border="1px solid #eee", border_radius="0.5rem"),
spacing="4"
)
def tag_pill(tag: str, count: int = 0):
return rx.badge(
f"{tag} ({count})" if count else tag,
on_click=State.set_tag_filter(tag),
cursor="pointer",
color_scheme="blue" if tag == State.tag_filter else "gray"
)
async def tags_bar():
s = await State.stats()
tags = [("all", s["total"])] + s["tags"]
return rx.hstack(*[tag_pill(t[0], t[1]) for t in tags], spacing="2", wrap="wrap")
def note_row(note: Note):
return rx.hstack(
rx.hstack(
rx.checkbox(is_checked=note.done, on_change=State.toggle_done(note.id)),
rx.text(note.content, text_decoration="line-through" if note.done else "none"),
),
rx.badge(note.tag, color_scheme="green"),
rx.button("π", on_click=State.delete_note(note.id), color_scheme="red", size="1"),
justify="between", width="100%"
)
async def notes_list():
items = await State.notes_filtered()
return rx.vstack(*[note_row(n) for n in items], spacing="2", width="100%")
"""
We design modular UI components including sidebars, tag filters, and separate comment lines. We use Reflex elements such as vstack, hstack and suspense to build responsive layouts. We ensure that every UI element directly reflects state changes in real time. Check The complete code is here.
app_py += """
def dashboard_page():
return rx.hstack(
sidebar(),
rx.box(
rx.heading("Dashboard", size="8"),
rx.cond(State.user != "", rx.text(f"Hi {State.user}, here is your activity")),
rx.vstack(
rx.suspense(stats_cards, fallback=rx.text("Loading stats...")),
rx.suspense(tags_bar, fallback=rx.text("Loading tags...")),
spacing="4"
),
padding="2rem", width="100%"
),
width="100%"
)
def board_page():
return rx.hstack(
sidebar(),
rx.box(
rx.heading("Notes Board", size="8"),
rx.hstack(
rx.input(placeholder="search...", value=State.search, on_change=State.set_search, width="50%"),
rx.button("Toggle sort", on_click=State.toggle_sort),
rx.button("Clear done", on_click=State.clear_done, color_scheme="red"),
spacing="2"
),
rx.hstack(
rx.input(placeholder="note content", value=State.new_content, on_change=State.set_new_content, width="60%"),
rx.input(placeholder="tag", value=State.new_tag, on_change=State.set_new_tag, width="20%"),
rx.button("Add", on_click=State.add_note),
spacing="2"
),
rx.cond(State.toast_msg != "", rx.callout(State.toast_msg, icon="info")),
rx.suspense(notes_list, fallback=rx.text("Loading notes...")),
padding="2rem", width="100%"
),
width="100%"
)
app = rx.App()
app.add_page(dashboard_page, route=" title="RC Dashboard")
app.add_page(board_page, route="/board", title="Notes Board")
app.compile()
"""
pathlib.Path("app.py").write_text(app_py)
subprocess.run(["reflex", "run", "--env", "prod", "--backend-only"], check=False)
Finally, we assemble the dashboard and kanban pages and compile the entire Reflex application. We add navigation, input fields, buttons and real-time statistics to create a fully interactive interface. Finally, we run the backend server that brings our advanced Reflex application to life.
In summary, we developed and ran a fully functional Reflex application that integrated stateful logic, dynamic components, and a persistent SQLite database, all from Python. We witnessed how easy it is to define front-end and back-end behavior using a unified reactive framework. Through this step-by-step process, we gained practical insights into managing asynchronous state updates, writing UI elements declaratively, and extending applications with multi-page navigation and analytics.
Check The complete code is here. Please feel free to check out our GitHub page for tutorials, code, and notebooks. In addition, welcome to follow us twitter And donβt forget to join our 100k+ ML SubReddit and subscribe our newsletter. wait! Are you using Telegram? Now you can also join us via telegram.
Asif Razzaq is the CEO of Marktechpost Media Inc. As a visionary entrepreneur and engineer, Asif is committed to harnessing the potential of artificial intelligence for the benefit of society. His most recent endeavor is the launch of Marktechpost, an AI media platform that stands out for its in-depth coverage of machine learning and deep learning news that is technically sound and easy to understand for a broad audience. The platform has more than 2 million monthly views, which shows that it is very popular among viewers.
π FOLLOW MARKTECHPOST: Add us as your go-to source on Google.