Coming from Streamlit
Streamlit is a great tool that popularized the “script as app” pattern. webwrench takes a different architectural approach that you’ll want to understand.
Key Conceptual Differences
| Concept | Streamlit | webwrench |
| Execution model |
Full script reruns on every interaction |
Runs once; callbacks update specific elements |
| Update granularity |
Entire page re-renders |
Surgical patches to individual elements |
| Dependencies |
Many (tornado, protobuf, pandas, etc.) |
Zero runtime dependencies |
| Frontend |
Custom React app |
bitwrench.js (lightweight, bundled) |
| Protocol |
WebSocket + protobuf |
SSE + JSON POST |
| Static export |
Not supported |
Built-in ww.export() |
| Multi-page |
File-based routing |
Decorator-based routing (@app.page) |
Side-by-Side Examples
Hello World
| Streamlit | webwrench |
import streamlit as st
st.title("Hello")
st.write("World")
|
import webwrench as ww
ww.title("Hello")
ww.text("World")
ww.serve()
|
Slider with Chart
| Streamlit | webwrench |
import streamlit as st
n = st.slider("Scale", 1, 10, 1)
# Chart rerenders every time
st.bar_chart([d * n for d in data])
|
import webwrench as ww
chart = ww.chart(data, type="bar")
s = ww.slider("Scale", min=1, max=10)
@s.on_change
def update(n):
chart.update([d * n for d in data])
ww.serve()
|
Columns
| Streamlit | webwrench |
col1, col2 = st.columns(2)
with col1:
st.write("Left")
with col2:
st.write("Right")
|
cols = ww.columns(2)
with cols[0]:
ww.text("Left")
with cols[1]:
ww.text("Right")
|
Things You Won't Need
st.cache_data / st.cache_resource — webwrench doesn't rerun, so no caching needed for the execution model
st.session_state dictionary — use ctx.state.attr attribute style in app mode
streamlit run CLI — just python your_app.py
Things That Are Better
- No full-page reruns means faster interactions
- Static HTML export for sharing reports
- Zero dependencies means simpler deployment
- Standard Python execution — no magic rerun behavior