
Picture by the writerWhen we talk about Azgar, we often think about using it to analyze data or create a machine learning model. It is less common to discuss making complete web applications with a simple prototype using libraries Streamlit Or Thypepie.
However, a library called Reflex The web application offers the properties of development that counter other programming languages. Fully, this open source library helps users to create anything from small data science apps to large, multi -page websites. With strong flexibility yet, with intuitive codes, we can easily measure web development with reflection.
In this article, we will learn the basics of creating pure web application with reflexes.
Build web apps with reflexes
In this tutorial, we will refreshing the web application construction standards. Best methods IT, it is advisable to use the virtual environment to avoid disrupting the overall environment.
Keeping it in mind, we will start developing our reflex web application by installing a reflex library using the code below:
After that we will examine a new project and start a new application and start a reflex. Use the following code, but change test_app Name of your own folder.
mkdir test_app
cd test_app
reflex initThe aforementioned code indicates the questions you want to make the project with a pre -created template.
![]()
![]()
Select this tutorial, the empty reflex app, and you will see the new project structure you designed as below.


Run the following command to see if your reflex request runs properly:
See the local URL serving application. If it works well, you’ll look like something like the bottom icon:
![]()
![]()
This is the support of the basic web application that is developed by reflex. We will build some more sophisticated later, but we will start with the basic principles.
Let’s start understanding the ingredients used to build a web application at the Reflex Library. Before, open
test_app.py And replace its contents from the following code:
import reflex as rx
class State(rx.State):
count: int = 0
def increment(self):
self.count += 1
def decrement(self):
self.count -= 1
def 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)It will show a website below.
![]()
![]()
Let’s break what is happening in the aforementioned code.
First, we describe the state, which are variables (called vars) And functions (called event handlers) Who can change the condition of the application.
For example, we describe a single variable called count It contains a number of 0 with the initial price.
class State(rx.State):
count: int = 0Then we have the event’s handlers – the function within the state that edit the variables in response to user actions. In the aforementioned code, we describe the event’s handlers like this:
def increment(self):
self.count += 1
def decrement(self):
self.count -= 1Next, we describe the web application UI like this:
def 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",
)The above functions describe the web application interface and use the following components to build the UI:
rx.hstack: Used to stack the elements horizontallyrx.button: A button used to show that an event trigger when clickingrx.heading: Used to display text in different sizes
As you can see in the aforementioned code, the heading component refers to count Variation in the state, and when clicked, each button stimulates a function in the state.
You can use many components to build a web application. See reflexes Documents of Components.
Finally, we specify the request and add the components to the base route with the following code:
app = rx.App()
app.add_page(index)This is a simple explanation of these important ingredients that reflexes uses to build a web application.
With the aforementioned explanation, let’s create a more modern web application with reflexes. In the example below, we will produce an application of a one -to -one list that can allow and remove the items.
import uuid
import reflex as rx
from typing import Any, Dict, List
class TodoState(rx.State):
todos: List(Dict(str, Any)) = ()
new_text: str = ""
current_filter: str = "all" # Select between "all", "active", "done"
# Derived values (computed from state)
@rx.var
def items_left(self) -> int:
return sum(1 for t in self.todos if not t("done"))
@rx.var
def items_left_label(self) -> str:
return "1 item left" if self.items_left == 1 else f"{self.items_left} items left"
@rx.var
def filtered_todos(self) -> List(Dict(str, Any)):
if self.current_filter == "active":
return (t for t in self.todos if not t("done"))
if self.current_filter == "done":
return (t for t in self.todos if t("done"))
return self.todos
# Events (mutate state)
@rx.event
def set_new_text(self, value: str):
self.new_text = (value or "").strip()
@rx.event
def add_todo(self):
text = (self.new_text or "").strip()
if not text:
return
self.todos.append({"id": str(uuid.uuid4()), "text": text, "done": False})
self.new_text = ""
@rx.event
def toggle(self, todo_id: str):
for t in self.todos:
if t("id") == todo_id:
t("done") = not t("done")
break
@rx.event
def remove(self, todo_id: str):
self.todos = (t for t in self.todos if t("id") != todo_id)
@rx.event
def clear_completed(self):
self.todos = (t for t in self.todos if not t("done"))
@rx.event
def set_filter(self, name: str):
if name in {"all", "active", "done"}:
self.current_filter = name
def filter_button(name: str, label: str) -> rx.Component:
return rx.button(
label,
size="2",
variant=rx.cond(TodoState.current_filter == name, "solid", "soft"),
background_color=rx.cond(
TodoState.current_filter == name, "blue.600", "gray.700"
),
color="white",
_hover={"background_color": "blue.500"},
on_click=lambda: TodoState.set_filter(name),
)
def render_todo_item(todo: rx.Var(dict)) -> rx.Component:
return rx.hstack(
rx.checkbox(
is_checked=todo("done"),
on_change=lambda _: TodoState.toggle(todo("id")),
size="2",
color_scheme="blue",
),
rx.text(
todo("text"),
flex="1",
color=rx.cond(todo("done"), "gray.500", "white"),
text_decoration=rx.cond(todo("done"), "line-through", "none"),
),
rx.icon_button(
"trash",
color_scheme="red",
variant="soft",
on_click=lambda: TodoState.remove(todo("id")),
),
align="center",
spacing="3",
width="100%",
)
def todo_input_bar() -> rx.Component:
return rx.hstack(
rx.input(
placeholder="What needs to be done?",
value=TodoState.new_text,
on_change=TodoState.set_new_text,
flex="1",
size="3",
background_color="gray.800",
color="white",
border_color="gray.600",
_placeholder={"color": "gray.400"},
),
rx.button(
"Add",
size="3",
background_color="blue.600",
color="white",
_hover={"background_color": "blue.500"},
on_click=TodoState.add_todo,
),
spacing="3",
width="100%",
)
def todo_list_panel() -> rx.Component:
return rx.vstack(
rx.foreach(TodoState.filtered_todos, render_todo_item),
spacing="2",
width="100%",
)
def footer_bar() -> rx.Component:
return rx.hstack(
rx.text(TodoState.items_left_label, size="2", color="gray.300"),
rx.hstack(
filter_button("all", "All"),
filter_button("active", "Active"),
filter_button("done", "Done"),
spacing="2",
),
rx.button(
"Clear Completed",
variant="soft",
background_color="gray.700",
color="white",
_hover={"background_color": "gray.600"},
on_click=TodoState.clear_completed,
),
justify="between",
align="center",
width="100%",
)
def index() -> rx.Component:
return rx.center(
rx.card(
rx.vstack(
rx.heading("Reflex To-Do", size="6", color="white"),
todo_input_bar(),
rx.separator(border_color="gray.700"),
todo_list_panel(),
rx.separator(margin_y="2", border_color="gray.700"),
footer_bar(),
width="min(720px, 92vw)",
spacing="4",
),
size="4",
width="min(760px, 96vw)",
shadow="lg",
background_color="gray.900",
),
min_h="100vh",
padding_y="8",
background_color="black",
)
app = rx.App()
app.add_page(index, route=" title="Reflex To-Do")The result of the application will look like the icon below.
![]()
![]()
In the above code, the flow mainly serves as follows:
- The app has a small memory: your work, what are you typing, and which filter is selected.
- You type in the box and the text is stored when you type.
- You press “Add” and the work is saved (with ID) and the box is cleaned.
- The list immediately refreshes to show what is in memory.
- Each task row contains a checkbox and trash icon. Checked the completion of the toggle; Removes work in the trash.
- Three filter button (all / enabled / complete) changes which work looks.
- The footer shows how many works are not done and allows you to “completely complete”.
Some important discriminations – which include the first added basic ingredients – they include:
- Decorate with
@rx.eventDeclaration of events within the state. - Decorate with
@rx.varTo create a variable derived in the state. - Use
rx.ComponentSignature at the time to re -use UI helper for your reflex application.
This is a basic explanation and example of how reflex works. Try it yourself and make a web application you need with purezigar.
Conclusion
Reflex is an open source library that allows us to create web applications in purezigar with an easy but intuitive code pattern. It allows users to set up logic and UI in one place. This is a useful library for newcomers and professional developers who want to make an application with Azgar.
I hope it has helped!
Cornelius Yodha Vijaya Data Science is Assistant Manager and Data Writer. Elijan, working in Indonesia for a full time, likes to share indicators of data and data through social media and written media. CorneLius writes on various types of AI and machine learning titles.