So it’s a bit “out there” but the JupyterLab notebook is currently able to be completely “hosted” on a static web page using Pyodide kernels using web assembly. This is Python running directly within the user’s browser. No application server needed:
JupyterLite also has a really easy way to bundle up notebooks and python environments all within a nice reproducible archive.
I can see this model being absolutely awesome for Streamlit. Imagine being able to share a local version of a Streamlit app just by sending someone an archive that opens up the web browser and all of the Python runs within the user’s browser, without needing any Python installed. Self hosting Streamlit would be multiple orders of magnitude easier, one could host a Streamlit app with GitHub pages.
Anyway, here’s my proposal, support a Pyodide backend for Streamlit allowing Streamlit apps to run completely within the browser
For such rewrite, I think the Streamlit repository have to be forked
In the case of Jupyter, the server and frontend are decoupled and the connection between them is highly abstracted. This is the reason why Jupyter Lite can be developed independently from the Jupyter and can import Jupyter core into its Pyodide runtime.
Surely not forked, instead just have the required preparatory refactoring rework undergone within the main repository first achieving the required decoupling. I think its quite important to keep this ecosystem/community tightly knit and not split out into forks.
Even if that decoupling work takes ~6 months worth of pull requests, for the long term maintainability of something like this that investment is worth it.
Another benefit I should add for the Streamlit company is that the costs for running the Streamlit cloud hosting could be significantly reduced when Python is running client side instead of on Streamlit servers. Also, in cases where the data being processed is sensitive, having that data never leave the client’s machine is quite beneficial.
I didn’t want to refer to the project fork.
I wanted to say just about technical issue that some fixes are needed on the core and the development must be tightly coupled with the core development, which is different from Jupyter Lite. The fork here simply means “forking a branch in the main repo” unlike Jupyter Lite, which is a separate repo independent from the core.
As a separate discussion, I’m not sure if it can be merged into the main stream - the core design/development is not community-driven, but the core development team of the company does.
Of course the forked development can be merged into the main branch, but maybe not. It must be discussed with the core dev team.
It’s a project management/design decision and out of scope I wanted to write about in the post.
The advantages you wrote is true and such information is important to discuss with the core dev team, I think.
If I add something,
I made my first progress: Stlite playground
(On this page, ~50MB resources will be loaded including the Pyodide runtime and some Python packages)
On this sample page you can see that Streamlit is running on the browser. There is no server-side Python; it’s an SPA hosted on GitHub Pages. And you can see the logs on the dev tool console.
I set up a code editor on this playground app, so you can try to edit and save the code and run it.
As this sample is built as a PWA, it works in an offline environment after the first loading and caching, and it also can be installed to your local environment. I think this is one major possibility of the browser-based Streamlit - it works as a desktop/smartphone app (loading runtime is still slow though).
Note that it’s just a first example at the POC stage, where only a subset of Streamlit functionality is working and there are many things to implement and improve.
For example, components such as st.table or st.line_chart that are using PyArrow, PyDeck or PyZMQ (or maybe others) are not working .
Custom components are also not supported.
I’m currently trying to build a distributable package or some other ways to reuse this library so that developers can use this on their web pages, such as npm package, PyScript-like package that is usable via script tag, or Jupyter Lite-like iframe embedding.
Technically, these libraries have native code e.g. C-extensions that have to be compiled with Emscripten for Pyodide runtime, which is kind of tough. Supporting these components is one major task. ↩︎
Technically, I did “fork” the streamlit main repo: Comparing streamlit:develop...whitphx:stlite · streamlit/streamlit · GitHub
because the original Streamlit cannot run on Pyodide as it uses some features that Pyodide/WASM runtime do not support, such as threading. I had to replace them with Pyodide-compatibe modules, for example, threading → asyncio, but also took care of keeping the original code as much as possible so that it will be easier to merge the upstream changes into the forked repo.