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

ConceptStreamlitwebwrench
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

Streamlitwebwrench
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

Streamlitwebwrench
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

Streamlitwebwrench
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

Things That Are Better