00:00:00Are you a hardcore Python fan? I mean, like, are you someone who just wants to write Python code
00:00:05and nothing else? Well, if that's you, then I got just the thing for you. It's a framework called
00:00:11Reflex and it aims to solve the friction and complexity involved in turning full-stack Python
00:00:17code into production-ready web applications. In this video, we're going to look at what
00:00:22Reflex is, how it works, and let's see what the hype is all about.
00:00:30So the primary problem Reflex is trying to solve is the requirement for Python developers to learn
00:00:36an entirely different stack, including JavaScript, React, routing, and bundlers, just to be able to
00:00:43build a functional web interface for their code. Reflex allows developers to build full-stack apps
00:00:50in 100% pure Python, so you can just focus on using one language for the entire stack without
00:00:56context switching. They also claim that since their launch, developers have built over 1 million apps
00:01:03with this framework and they also claim that 30% of Fortune 500 companies are using it for their
00:01:10internal tooling. And recently, they've been weighing heavily into AI and they launched a
00:01:15tool called Reflex Build, which basically allows you to vibe code your app from a single prompt.
00:01:21Plus, they support integrations for other SDKs and tools that let you easily connect your app
00:01:26to other popular services like Databricks, Okta, Stripe, AWS, etc. Now that all sounds impressive,
00:01:34but I want to get my hands dirty and try this code on my own to see how it actually works.
00:01:40Let's start by creating a new directory, ReflexTest, and then cd into it. From here,
00:01:44the docs say we can run these three commands to start our Reflex project. So let's start
00:01:48by running pip install reflex and then reflex init. And here we are offered to get started with one of
00:01:53their templates. But for this demo, we're just going to keep it simple and choose the blank
00:01:57reflex app option. Once that's done, we can open the project in our code editor. And if we open the
00:02:02reflex test folder, this is where our entire app lives in the reflex test.py file. We can see that
00:02:09it has an RX component section and a state class. Let's run Reflex Build in our terminal to launch
00:02:15our app. And it spins up our app on port 3000. And we can see the result here in the browser.
00:02:20So now let's see how Reflex manages state. We can start by adding a simple count variable.
00:02:25And to change this value, we also need to define a function which will do that. So underneath the
00:02:29count variable, we can define an increment function that will just increase the count by one. And it is
00:02:34recommended to add the RX event decorator on top, which enables proper static type checking and
00:02:39ensures event handlers receive the correct number and types of arguments. And then we can add a
00:02:44simple button in the return statement of the RX component. It will show us the count in the text
00:02:48field and it will trigger the increment function on click. And Reflex supports hot reloading. So if
00:02:53we now save the file and open the browser, we now see our count button which increments the value
00:02:58every time we press it. Now let's try something more interesting. Let's create an array of items
00:03:02in our state. And in theory, we should be able to render these items out as a list by doing this
00:03:08inline for loop. But this will not work because this value is not known at compile time. You see,
00:03:13the way Reflex works is that when you run your app, the front end gets compiled to JavaScript
00:03:18code that runs in the browser, which is called compile time in Reflex terms. The back end stays
00:03:23in Python and runs on the server during the lifetime of the app. And this is called runtime
00:03:27in Reflex terms. So we cannot do a pure Python for loop in our component render, but we can do
00:03:32pure Python operations outside the component render block. But how do we loop through the items in the
00:03:37component block? Well, for this case, we need to define a simple render item function that will
00:03:42render out our item like so. And then we need to use the RxForEach function in the component render
00:03:47block to do our for loop. And now we see our items rendered properly on the app. The same applies with
00:03:53conditional rendering. We cannot do plain if-else statements in the return block like so. Instead,
00:03:58we need to use the RxConditional function like so. And if we now click the button more than five
00:04:02times, we will see our text pop up on our app. The last thing to look at is how can we fetch and
00:04:08render data. For this demo, let's just fetch a random useless fact from the random useless facts
00:04:12API and display it in a text box. First, let's add a boolean variable that will indicate if our
00:04:17data is fetching and a simple empty string that will hold our fact. And then we can define an
00:04:22asynchronous data fetching function that will set data fetching to true. And then it will use the
00:04:27HTTPX library to fetch our random useless fact and store it in our fact state variable. And I'm also
00:04:33adding a slight delay of one second with isync IO so we can actually see the data fetching in real
00:04:38time. After the operation is done, we set the data fetching boolean back to false. And notice how we
00:04:43added the yield operation here. So anytime we want to update the UI multiple times in an event
00:04:48handler, we can use yield when we want to send an update to the renderer. So in this case, as soon
00:04:52as data fetching is changed, we want to update our UI to reflect that change. And let's not forget to
00:04:57add the HTTPX and async IO imports at the top. And lastly, in our render function, we can do a simple
00:05:03RX conditional function to show a loading spinner or the fact based on the current state. And if we
00:05:08want this function to trigger every time we load the page, we need to add a decorator for our RX
00:05:12component that will trigger our fetch data function on page load. And now if we reload our page, we can
00:05:18see our random useless fact being fetched and rendered on the page. The last thing I want to do
00:05:22here is look at the dot web folder. As we can see here, everything we just wrote is compiled and
00:05:27rendered onto a react app under the hood, which uses vt and tailwind under its hood. And it even
00:05:33has a react router for its route handling. And to be honest, as soon as I saw this, I was super
00:05:38disappointed. I thought they had built like a custom JavaScript compiler or something original.
00:05:42But this just means that reflex is just another abstraction layer on top of react. So I kind of
00:05:47have mixed feelings about reflex. On one hand, the idea is really cool to have a single Python full
00:05:53stack framework that lets you write everything in pure Python. But I was super disappointed to
00:05:59find out that under the hood, it's just wrapping a react app and not using native Python. This just
00:06:05makes it more convoluted, because you are now forced to relearn a new architecture and understand
00:06:11how reflex handles state management, not to mention all the edge cases that can occur, you might as
00:06:16well just stick with react because it's a battle tested and solid framework. So if I were to create
00:06:22a project with a Python back end, I would still use a JavaScript framework for my front end.
00:06:28Reflex did not convince me to go full on Python full stack. But those are just my two cents. What
00:06:34do you think about reflex? Do you like this idea of a full stack Python framework like this one?
00:06:39I'm really curious to know what you think. And folks, if you enjoyed this video, be sure to let
00:06:44us know by smashing that like button underneath the video. And don't forget to subscribe to our channel.
00:06:50This has been Andris from better stack and I will see you in the next videos.