Full Blog TOC

Full Blog Table Of Content with Keywords Available HERE

Monday, June 9, 2025

Python Reflex

 




In this post we review the python reflext framework


The reflex framework is yet another attempt at creating GUI without using javascript, and without the need of create APIs on the server side for each operation. We've already seen some of such attempts, see for example: Streamlit. The reflex generates HTML and javascript with react components, and hence can be even deployed as a production solution.


Small Attempt At A Demo

To check this framework, I've created a small application with a login page, and the increment/decrement example from the reflex getting started document.

To start we need to install the reflex library, create a template for our application, and run it. The updates should be done in the ref/ref.py file, and the framework includes a hot-reload support, so there is no need of restarting for every code change.


pip install reflex
reflex init
reflex run


The ref/ref.py is the following:


import reflex as rx


class State(rx.State):
count: int = 0
user_name: str = ''
password: str = ''
user_id: int = 0

def login(self):
print(self.user_name)
print(self.password)
self.user_id = 42
return rx.redirect("/")

def verify_logged_in(self):
if self.user_id == 0:
return rx.redirect("/login")

def set_user(self, value):
self.user_name = value

def set_password(self, value):
self.password = value

def increment(self):
self.count += 1

def decrement(self):
self.count -= 1


@rx.page()
def login() -> rx.Component:
return rx.vstack(
rx.input(
State.user_name,
placeholder="Enter User Name",
on_change=State.set_user
),
rx.input(
State.password,
placeholder="Enter Password",
on_change=State.set_password,
),
rx.button(
"Login",
on_click=State.login
)
)


@rx.page(on_load=State.verify_logged_in)
def index() -> rx.Component:
return rx.container(
rx.color_mode.button(position="top-right"),
rx.vstack(
rx.heading(f"Welcome user {State.user_id}", size="9"),
rx.hstack(
rx.button(
"Decrement",
color_scheme="ruby",
on_click=State.decrement,
),
rx.button(
"Increment",
color_scheme="grass",
on_click=State.increment,
),
),
rx.heading(State.count, font_size="2em"),
spacing="5",
justify="center",
min_height="85vh",
),
)


app = rx.App()
app.add_page(index)
app.add_page(login)


And it is working like a charm (Almost).


Notice the state is managed on the server side and is updated using a websocket that includes a message for any state update. This is a very nice idea that reduces coding requirements, however the load on the server would be very high for multi-users application.

The state is actually saved per tab, so any tab keeps a session with the sever, and hence even I had logged-in on one tab, I need to re-login on the other tab.


Final Notes

As always, attempts to save work on the javascript/react and the server side APIs are nice for development stages but are bad for production in both performance aspect and development aspect.

While javascript is a unstructured, non-compiled, error prune language, it is still the best alternative for production, supplying the performance and flexibility required for a GUI application.

In addition, reflex claim to reduce need to use a new language, but you will need to invest a lot of time to understand the reflex components and how to use them correctly. In case you have a problem, reflex might show a useful error, but in many cases it show a non-user-friendly error, and good luck finding assistance for such error in a small reflex community.

It is a nice tool for a single developer just asking for a quick UI for his own created solution engine, but don't expect anything else from reflex.


No comments:

Post a Comment