Powering the future of streamlit software with st-page-state

st-page-state is an architectural framework designed to transform Streamlit into a foundation for enterprise-grade internal systems. It replaces loose, brittle st.session_state dictionaries with typed, declarative classes that ensure your application survives the “refresh test”.

The Problem

Native Streamlit state management relies on magic strings, lacks type safety, and is volatile. If a user refreshes their browser or shares a link, their complex “work-in-progress” context is lost.

The Technical Solution

st-page-state treats state as a first-class citizen through structured schemas and bi-directional URL synchronization.

For Developers (DX):

  • Typed Schemas: Use StateVar to define state with strict types (int, bool, list[str], datetime.date, etc.) and default values.

  • Namespace Isolation: Every class has its own isolated storage bucket, eliminating key collisions in modular, large-scale apps.

  • Lifecycle Hooks: Define on_init and on_change logic directly within your state models to manage side effects cleanly.

  • Introspection: Use .dump() to instantly export state for API payloads or logging.

For Users (UX):

  • Indestructible Context: Every interaction is synced to the URL. Progress survives page refreshes and can be shared instantly via deep linking.

  • Intelligent URL Management: url_selfish automatically purges stale parameters from other modules, keeping the address bar clean and professional.

  • State Defense: restore_url_on_touch ensures that if a user manually deletes a URL parameter, it is instantly repopulated from the session context upon access.

  • Cross-Module Synergy: share_url_with allows independent components—like a global sidebar and a main workspace—to coexist in the URL seamlessly.

Implementation Example

import streamlit as st
from st_page_state import PageState, StateVar

class AppWorkflow(PageState):
    class Config:
        url_prefix = "app_"            # Module isolation
        url_selfish = True             # Claims URL focus for this component
        share_url_with = ["NavState"]  # Explicitly coexists with navigation

    task_id: str = StateVar(default="", url_key="tid")
    priority: int = StateVar(default=1, url_key="pri")

# Programmatically claiming focus cleans the URL and sets the application context
if st.button("Resume Task"):
    AppWorkflow.focus()

Stop treating your users’ progress as temporary. Build persistent, modular, and professional systems.

GitHub: [https://github.com/ju-sants/st-page-state]

PyPI: pip install st-page-state

1 Like

I’m evaluating this for a Portfolio Analytics engine where URL-persistence for complex MWRR/TWRR ‘what-if’ scenarios is critical. Native session_state is too brittle for institutional-grade reporting.

1 Like