Composable, typed Streamlit applications with a declarative component model.
Project description
Streamtree
Composable, typed Streamlit applications — a small Python layer that turns UIs into declarative trees instead of long imperative scripts.
Streamtree keeps Streamlit’s execution model and widgets, but adds components, virtual elements, scoped session state, and a path toward Pydantic-typed forms and props. No JavaScript is required for the core experience.
Why Streamtree
| Without Streamtree | With Streamtree |
|---|---|
| Layout and widgets interleaved in one script | @component functions return a tree of elements |
st.session_state keys scattered and stringly |
state() keys scoped to the render path |
| Hard to snapshot or reason about structure | streamtree.testing.render_to_tree() for structure checks |
Streamtree is not a React clone, a browser framework, or a JS build step. It is an architecture layer for teams who want maintainable Streamlit apps.
Features
- Python-first — decorators, plain functions, standard typing
- Pydantic v2 in the default install for typed models and validation helpers
- Declarative layouts —
Page,Card,Grid,VStack,Form,Tabs,Sidebar,Routes,ErrorBoundary, … - Session-backed state —
state,toggle_state,form_state,memo,cache - Streamlit renderer — virtual tree →
st.*on each rerun - Testing helpers — serialize trees for snapshots (
render_to_tree) - Typed trajectory — roadmap and dependency strategy center on Pydantic and curated optional extras
Requirements
- Python 3.10+
- Streamlit ≥ 1.28, Pydantic v2, and typing-extensions (declared in
pyproject.toml)
Install
From PyPI (after you publish this version):
pip install streamtree==0.2.0
From a clone (editable, with dev tools):
git clone https://github.com/streamtree-dev/streamtree.git
cd streamtree
pip install -e ".[dev]"
# or, with uv:
uv sync --extra dev
Optional install groups (tables, charts, ui, auth, asyncio, cli) are stub extras today; see STREAMTREE_DEPENDENCY_STRATEGY.md. Combine with e.g. pip install "streamtree[tables,charts]" as wrappers land.
Quick start
from streamtree import component, render
from streamtree.elements import Button, Card, Page, Text
from streamtree.state import state
@component
def Counter():
count = state(0)
return Card(
Text(f"Count: {count()}"),
Button("Increment", on_click=lambda: count.increment(1)),
Button("Reset", on_click=lambda: count.set(0)),
)
if __name__ == "__main__":
render(Page(Counter()))
Run the bundled demo from the repo root:
streamlit run examples/counter.py
streamlit run examples/routed_app.py
Layout and state at a glance
Grid of components
from streamtree.elements import Grid
Grid(
UserCard(user1),
UserCard(user2),
columns=2,
)
Bound text input
from streamtree.elements import TextInput
from streamtree.state import state
search = state("")
TextInput(label="Search", value=search)
Routing, error boundaries, and forms (0.2+)
Query-param routing — keep the active page in sync with st.query_params (see streamtree.routing.sync_route and the Routes element).
Error boundaries — wrap fragile subtrees: ErrorBoundary(child=..., fallback=..., on_error=optional).
Pydantic helpers — streamtree.forms.str_field_names, model_validate_json, and format_validation_errors for small JSON or string-keyed forms.
App context — streamtree.app_context.provider(theme="dark") / lookup("theme") for values you do not want to thread through every @component signature.
Project layout
src/streamtree/ # installable package
app_context.py # provider / lookup DI bag (contextvars)
routing.py # query-param route sync + set_route
forms.py # Pydantic str-field + JSON validation helpers
core/ # elements, @component, render, render_context
elements/ # layouts + widgets
state/ # session state helpers
renderers/ # Streamlit backend
testing/ # tree serialization for tests
docs/ # plan, roadmap, dependency strategy
examples/ # counter.py, routed_app.py
tests/ # pytest
Documentation
| Document | Contents |
|---|---|
| STREAMTREE_PLAN.md | Vision, goals, architecture, risks |
| STREAMTREE_ROADMAP.md | Phased delivery and dependency alignment |
| STREAMTREE_DEPENDENCY_STRATEGY.md | Base vs optional deps, extras, wrapper-first API |
| CHANGELOG.md | Version history |
Contributing
With uv (recommended):
uv sync --extra dev
uv run ruff check src tests
uv run ty check src
uv run pytest
With pip:
pip install -e ".[dev]"
ruff check src tests
ty check src
pytest
CI runs the same checks on Python 3.10–3.12 (see .github/workflows/ci.yml).
Publishing
Automated (recommended): configure the PYPI_API_TOKEN repository secret (PyPI → Account → API tokens, scoped to this project). After main is green in CI, push a version tag matching v* (for example v0.2.0 for this release); .github/workflows/release.yml runs ruff, ty, pytest (with the same coverage gate as CI), then uv build, and publishes via pypa/gh-action-pypi-publish.
Manual: build artifacts with uv build (or python -m build), then upload the contents of dist/ to PyPI using twine or uv publish. Keep version in pyproject.toml, streamtree.__version__, tests/test_package_meta.py, and CHANGELOG.md aligned when you cut releases.
License
MIT — see the LICENSE file.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file streamtree-0.2.0.tar.gz.
File metadata
- Download URL: streamtree-0.2.0.tar.gz
- Upload date:
- Size: 43.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f2eb7de26d3cc20de6f37319a9860b77ed254f39476a2f16191e5fb2a9cceaa9
|
|
| MD5 |
652aded9488744caafeef67fb05e52db
|
|
| BLAKE2b-256 |
388104aa0e49f25f469be045cc155334b3841c65dc00cc220cb17e96fa424b90
|
File details
Details for the file streamtree-0.2.0-py3-none-any.whl.
File metadata
- Download URL: streamtree-0.2.0-py3-none-any.whl
- Upload date:
- Size: 21.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0d03fd9f7be36532ce7f5b6d1a267700232db28223f77bf38ce2a58ebe30facc
|
|
| MD5 |
6c44aacf04200bc22379d697b3b7eea1
|
|
| BLAKE2b-256 |
55cb139f55cab7533e8c96c50b38fca05dc5009b0345d34c259cc5fa1956b585
|