Three Python lines make the first useful app
Streamlit's README turns 3 lines of executable Python into a browser app. The code imports Streamlit, creates a slider, and prints the squared value. streamlit run streamlit_app.py opens it. A data scientist can put controls around an analysis while staying in Python, without first designing an API and a separate client application.
The surface extends well beyond that example. Streamlit has tables, charts, forms, multipage navigation, chat elements, and custom components. Community Cloud provides the hosted route advertised in the README, while Apache-2.0 licensing leaves self-hosting open. The framework is most convincing for internal reports, model controls, and review queues where useful access matters more than a bespoke application shell.
One browser interaction can rerun the whole Python file
Streamlit's architecture reruns 1 file of Python code from top to bottom after each browser interaction, while every tab creates its own session. That model keeps the page readable as Python: the order in the file largely matches the order on screen. It also means an innocent widget change can repeat database reads, model setup, or data transforms unless the app handles state and expensive work deliberately.
There are 2 main cache decorators. st.cache_data is for serializable results and returns copies, while st.cache_resource shares objects such as models or database connections across reruns and sessions. Session State preserves per-session values. Those tools make serious apps possible, but they also become application architecture. A prototype that feels linear can accumulate cache invalidation rules and concurrency questions as more users arrive.
What happened when we ran it
In our sandbox, we measured a 28-second install for commit 0db4d54, adding 35 Python packages and using 37 MB on disk. The container had 3 CPUs, 8 GB of RAM, Python 3.12 on Debian, no secrets, and no elevated privileges. Pip-audit reported 0 known vulnerabilities in that installed environment. Our measurement setup covered repository mechanics, not app latency or server capacity.
The build ran for 9 seconds and exited with code 1. The supplied measurement summary contains no error tail, so it does not reveal which command failed or why. Blaming Protobuf, Node, or a missing Debian package would be guesswork. Tests were skipped because the harness found no test script or target, so our run provides no passing test count.
The checkout itself was substantial: 9,984 files, about 667,646 lines of source, and 153.1 MB. We found 44 CI workflow files, no Dockerfile, and no tests directory. That last observation describes the scanned directory layout, not an assertion that Streamlit has no tests. The repository's Makefile names separate Python, frontend, integration, and browser-test commands, but the generic harness did not select one.
The source checkout needs more than the 37 MB Python environment
Streamlit's 153.1 MB source checkout needs Python, Node, Yarn, Protobuf, and Playwright tooling. The contributor guide tells Ubuntu developers to install build tools and a Protobuf compiler, then use nvm for the pinned Node version and Corepack for Yarn. The Python side uses uv, and Playwright can install browser binaries and system libraries. This is a web framework codebase, even though its users mainly write Python.
That distinction gives the 9-second build failure its proper weight. It does not show that a normal Streamlit app is broken, because the 28-second dependency install completed. It does show that a fresh Python-focused container was insufficient for the build target the lab chose. If you plan to patch the framework, reproduce the documented contributor environment and run the relevant Make targets before estimating the work.
Queued reruns and changing rows need application-level checks
Confirmed P2 issue 17215 reports that a Custom Components v2 trigger can disappear when another widget update arrives while a rerun is queued. The reproduction uses a 5-second fragment and was reported against Streamlit 1.63.0 and 1.64.0. A built-in button survives the same sequence. Component authors handling payments, approvals, or destructive actions should test overlapping events instead of assuming every browser trigger reaches Python.
Issue 17026 documents a different state hazard. In its example, selecting TICK-102, inserting a new row, and then acting on the saved position closes TICK-101. The report says keyed dataframes and editors can retain positional selection or edit state after the data changes. Until the behavior changes, resolve actions against stable record identifiers and reject state created for an older frame.
Version 1.65.0 shipped four days before this review
Release 1.65.0 arrived on October 2, 2026. It added an on_change="ignore" mode to several widgets, required fields for text and number input, and alternative-text support across many display commands. The notes also list fixes for query-bound widgets, hung script threads, cached awaitables, and dialog reruns. This is active product work around the same execution model that creates Streamlit's tradeoffs.
GitHub showed 45,907 stars and 1,188 open issues and pull requests combined on October 6. The repository was pushed that same day, and current pull requests were receiving maintainer activity. The large queue should not be read as 1,188 bugs, but it does tell you to search for your exact widget and state pattern before choosing the framework for a sensitive workflow.
Outside pull requests are paused
GitHub listed 1,188 issues and pull requests as open when the README said outside code submissions were paused. Users can still file reproducible bugs, request features, comment on specifications, and publish custom components. The contributor guide attributes the pause to more incoming AI-assisted code than maintainers can review. For an organization that requires an upstream path for its own patch, that policy is a practical adoption limit.
Streamlit remains the shortest route here when a Python team wants a useful data app and accepts the framework's page model. Our 28-second install supports trying it. The failed 9-second source build argues for a separate contributor evaluation. Before a prototype becomes a production tool, test reruns with real data, identify stable record IDs, and decide whether a fix can wait for the maintainer team.

