Pycon.de: reinventing streamlit - Malte Klemm

Tags: pycon, python

(One of my summaries of the 2025 pycon.de conference in Darmstadt, DE).

He asked everyone who has used streamlit to stand up (75% stood). Then everyone who thought their dashboards were getting much too complex could sit down again. Only a few were left standing.

In 2015 he started out with a streamlit precursor based on bokeh. Around 2020 streamlit came around and it quickly gained a lot of popularity. He still uses streamlit and likes it. It is simple and easy.

But… people ask for more functionality. Or they add multiple pages. Then it slowly starts to break down. It doesn’t fit the streamlit paradigm anymore. You can use @st.cache_data to speed it up a bit if you do an expensive calculation. @st.fragment limits the execution scope: changes within a fragment only trigger the fragment to re-run. After a while, the cache_data and fragment decorators are only band-aid on a bigger problem. It breaks down.

He recently discovered https://reflex.dev/ . An open source framework to quickly build and deploy web apps. It is a pure python framework, so you don’t have to write typescript. But the big difference with streamlit is that the code is explicitly divided in frontend and backend.

  • The UI is a result of a function.

  • Changes are handled via events.

  • State variables are accessible by the frontend. And they are session-scoped (so every user gets its own state). Note: you can have more than one state, nesting them a bit, as they otherwise could get too big and unwieldy.

You have a State class/object with @rx.event-decorated methods that implement the events.

  • Input data is transformed to output data.

  • Input data can be changed by a widget.

  • Output data can end up in a widget.

  • Widget changes can trigger transformations.

You start with python code. A compiler/transpiler turns it into a next.js frontend and a fastapi backend. Events are passed back and forth via an api between the frontend and backend. The backend gives state updates to the frontend via a websocket.

Because it is compiled once before starting the dashboard, it is less dynamic/on-the-fly than streamlit: you have to do some rx.for_each(....) to loop over values.

  • If you know django+react or fastapi+react: use that if you know how to do it.

  • If you want simple dashboards: streamlit, dash, gradio.

  • The newcomers that aim at the middle ground because they are more explicit: reflex, rio, fasthtml. There’s a fasthtml-vs-streamlit talk tomorrow!

Some closing comments on why you might not want to use reflex:

  • Runtime errors in javascript are hard to debug.

  • You need to have a mental model of frontend vs backend.

  • The framework is moving fast (which is also good).

  • Performance and wide adoption: that’s still to be seen, it is still early days.

Something really useful that’s not in the documentation: AppHarness, which allows you to test the backend.

He tried to create a wrapper for streamlit in reflex, mostly to make it easier to move your existing dashboards slowly over to reflex. It is called relit, but it doesn’t work completely yet (and he hasn’t released it publicly yet, just ask him). And it was pretty hard to get to work :-) He thinks it might be used for writing tests for streamlit dashboards.

https://reinout.vanrees.org/images/2025/pycon-24.jpeg

Photo explanation: picture from our 2024 vacation around Kassel (DE)

 
vanrees.org logo

Reinout van Rees

My name is Reinout van Rees and I program in Python, I live in the Netherlands, I cycle recumbent bikes and I have a model railway.

Weblog feeds

Most of my website content is in my weblog. You can keep up to date by subscribing to the automatic feeds (for instance with Google reader):