Full-script reruns get slow in big apps; fragments make interactions local and enable live-updating panels.
A fragment is a function decorated with @st.fragment. When a widget inside the fragment changes, Streamlit reruns only that function, not the whole script. Widgets outside still trigger full reruns.
@st.fragment
def filters_and_chart():
metric = st.radio("Metric", ["visits", "signups"])
st.line_chart(load_data()[metric])Use fragments for self-contained parts of a page: a chart with its own controls, a form-like panel, a table editor. Pass run_every="10s" to rerun the fragment on a timer, which gives live dashboards without a full page refresh.
Things to know:
- Values computed inside a fragment are not visible to the rest of the script until a full rerun; share them via session state.
- A fragment's elements are redrawn in place on each fragment rerun. Its widgets must be drawn in its own body, not into containers created outside it.
st.rerun()triggers an immediate rerun of the whole app; inside a fragment,st.rerun(scope="fragment")reruns just the fragment.
Dialogs are fragments shown as a modal: decorate a function with @st.dialog("Title") and call it, typically from a button. Widgets inside the dialog rerun only the dialog; call st.rerun() to close it and refresh the app once the user confirms.
st.stop() ends the current run immediately, useful for guards such as "please upload a file first".
Example
import time
import streamlit as st
if "items" not in st.session_state:
st.session_state.items = ["apples"]
st.write("Full app run at", time.strftime("%H:%M:%S"))
@st.fragment(run_every="5s")
def live_panel(): # reruns alone, every 5 seconds
st.metric("Server time", time.strftime("%H:%M:%S"))
@st.dialog("Add item")
def add_item():
name = st.text_input("Item name") # typing reruns only the dialog
if st.button("Save") and name:
st.session_state.items.append(name)
st.rerun() # close dialog, refresh the whole app
live_panel()
if st.button("Add item"):
add_item()
st.write(st.session_state.items)
if not st.session_state.items:
st.stop() # nothing below runsRemember
@st.fragmentreruns only that function when its own widgets changerun_everyrefreshes a fragment on a timer for live views@st.dialogbuilds modals;st.rerun()andst.stop()control execution
Watch out for
- Expecting values computed inside a fragment to update the rest of the page without a full rerun.