Find exceptional developers at Hourlydeveloper. Get the expertise, solutions, and teamwork you need for success. Hire developers easily and boost your projects today!
Build Your Remote Team Now !
Streamlit Explained: Turn Python Scripts into Web Apps Fast
Streamlit Explained: Turning Python Scripts into Web Apps in Hours
Most data work starts in the same place. Someone writes a Python script. It cleans a spreadsheet, runs a model, or pulls numbers from a database. It works well on that person's laptop. Then a manager asks, "Can the sales team use this too?"
That question used to mean weeks of extra work and someone who knew HTML, CSS, JavaScript and a web framework. For a lot of small internal tools, the project simply stopped there.
Streamlit changed that. It is a free, open-source Python library that turns a script into a working web app when you add a few lines of code. You don't write HTML or JavaScript. If you can write Python, you can put a basic app in front of your team the same afternoon.
This guide explains how to turn Python scripts into web applications with Streamlit, how it compares with Flask, Django, Dash and Gradio, where it fits in machine learning and AI projects, and what happens when your app meets messy data, lots of users and unexpected errors. The language is kept plain, so non-developers can follow along too.
Why so many teams use it
Streamlit was released as open source in 2019. In March 2022, the cloud data company Snowflake bought it for roughly $800 million and still maintains it today.
A snapshot from public trackers in 2026:
Metric
Figure
GitHub stars
About 45,500 (August 2026)
Total downloads from PyPI
About 493 million
Downloads in a recent 30-day period
About 28 million
License
Apache 2.0 (free for commercial use)
Download counts include automated builds and test servers, so they overstate the number of real people using it. Even so, the numbers show this is no side experiment. A large share of Python data teams now build Python web apps with Streamlit as part of their normal work.
What is Streamlit, in plain words?
Streamlit is a Python library. You install it like any other package, import it at the top of your script, and call its functions to put things on a web page. st.title() puts a heading on the page. st.slider() adds a slider. st.line_chart() draws a chart. When you run the script through Streamlit, it opens in your browser as a web app.
Think of your script as a list of instructions. Normally the results appear in a terminal window only you can see. Streamlit follows the same instructions but draws each result on a web page that other people can open.
Below is a complete app. It is nine lines long.
import streamlit as st
import pandas as pd
st.title("Sales checker")
file = st.file_uploader("Upload a CSV", type="csv")
if file:
df = pd.read_csv(file)
st.dataframe(df)
st.line_chart(df, x="date", y="revenue")
Save it as app.py and run streamlit run app.py in your terminal. A browser tab opens at localhost:8501 with a title, an upload button, a table and a chart. That example sums up the whole idea of Streamlit.
The one idea you need to understand: the rerun
Every time a user does something, such as moving a slider, typing in a box or clicking a button, Streamlit runs your entire script again from top to bottom. It then compares the new output with the old page and updates only the parts that changed.
This is why Streamlit feels easy. You don't write code that says "when this button is clicked, update that chart." You write the script in order, and the slider value is just a variable the chart uses.
The downside is easy to see too. If your script loads a 2 GB file or a large model at the top, it would reload it on every click, and the app would crawl. Streamlit gives you three tools to deal with this:
• st.cache_data stores the result of a function that returns data, like a loaded CSV or an API response. The next run gets the saved copy instantly instead of doing the work again.
• st.cache_resource holds on to things you only want one copy of, such as a machine learning model or a database connection. All users of the app share it.
• st.session_state is a small memory box for each visitor. It keeps values like chat history or selected filters between reruns.
Once you understand reruns, caching and session state, you understand the core of how Streamlit behaves.
Main features
• Ready-made widgets such as sliders, text boxes, dropdowns, date pickers and file uploaders. Each takes one line of code and returns a normal Python value.
• Built-in charts, plus support for Plotly, Altair, Matplotlib and PyDeck maps.
• Interactive tables. st.dataframe shows sortable, searchable tables. st.data_editor lets users edit cells like a small spreadsheet and hands the edited data back to your code.
• Layout tools such as a sidebar, columns, tabs and expandable sections, plus multipage apps with a navigation menu.
• Chat elements. st.chat_message, st.chat_input and st.write_stream make it simple to build chatbot screens that show replies word by word.
• Fragments. A fragment is a part of the page that can rerun on its own, even on a timer, without rerunning the whole script. This matters a lot for live dashboards.
• Custom components made by the community, or written by you in JavaScript, for anything the built-in pieces can't do.
What kind of apps is Streamlit good for?
Streamlit does its best work when users care more about the data than the design. Good fits include internal dashboards, tools where staff upload a file and get an analyzed version back, machine learning demos, chat assistants built on large language models, "what-if" calculators and quick prototypes.
The common thread is speed. When a data team needs something usable by Friday, the fastest route is usually to build Python web apps with Streamlit rather than wait for front-end developers to become free.
It is a weaker fit for high-traffic public websites, strict brand designs, or large systems with many user roles and permissions.
The other options people compare with Streamlit
Four other tools come up in almost every comparison. They solve related problems in quite different ways.
Flask
Flask is a small, flexible Python web framework from 2010. It receives a web request, runs a Python function and sends back a response. Everything else, including how the page looks, is up to you, which means writing HTML templates, CSS and usually some JavaScript.
Its main features are URL routing, the Jinja templating system and many add-ons for databases, logins and forms. Because it is so light, Flask is also popular for building APIs.
Best for: REST APIs, model-serving endpoints and custom websites where you want full control.
Django
Django is the bigger, more complete framework. It follows a "batteries included" approach, which means most things a serious website needs come built in:
• A database layer (called an ORM) that lets you work with tables using Python classes
• A ready-made admin panel for managing data
• User accounts, logins and permissions
• Strong security defaults against common web attacks
Best for: large, long-lived web products such as marketplaces, content platforms, customer portals and SaaS products with many users and roles. It takes longer to learn but stays organized as the codebase grows.
Plotly Dash
Dash is made by Plotly and is built on top of Flask and React. Like Streamlit, it lets you build data apps in pure Python. The big difference is how it reacts to users. Dash uses "callbacks." You write a function and tell Dash: run this when that dropdown changes, and send the result to this chart. Only the linked parts update.
That means more code than Streamlit, but also precise control over layout and no full rerun on every click. Plotly also sells a paid enterprise version.
Best for: detailed dashboards with many linked charts where layout and performance matter.
Gradio
Gradio, now owned by Hugging Face, is built around one job: putting a friendly screen in front of a machine learning model. You tell it what goes in (text, an image, audio) and what comes out, and it builds the interface for you.
Gradio can create a public share link in one step and is the default way to host demos on Hugging Face Spaces. For anything beyond an input-to-output demo, such as a multi-chart business dashboard, it feels limited next to Streamlit.
Best for: quick model demos, research showcases and sharing a model with the ML community.
How Streamlit is different from Flask, Django, Dash and Gradio
All five tools put Python on the web, but they differ in ways that decide which one you should pick.
How you build the screen
With Streamlit, Dash and Gradio, you describe the screen in Python. With Flask and Django, you usually write HTML templates and CSS, plus JavaScript for anything interactive. For a data scientist, that single difference can be the gap between an afternoon and several weeks.
How the app responds to a click
Streamlit reruns the whole script. Dash runs only the callback linked to what changed. Gradio runs the function tied to that input or button. Flask and Django follow the classic web model: the browser sends a request, the server returns a page or data, and front-end JavaScript handles the rest.
Streamlit's approach is the easiest to write and read, but it uses the most computing power when a script is heavy.
How much control you get over the look
Flask and Django give total control because you write the front end yourself. Dash gives a lot of control through layout components and CSS. Streamlit offers themes and basic layouts, and Gradio is the most fixed. If your brand team wants a pixel-perfect look, Streamlit will frustrate them.
How far it scales
Django and Flask have run sites with millions of users for years. Dash copes well with production dashboards, especially with its enterprise tools. Streamlit keeps a live connection and a separate session for every open browser tab, so each user costs more server memory. It works comfortably for tens or low hundreds of people at the same time. Past that, it needs careful setup.
How quickly you get a first version
Streamlit and Gradio win easily here, often an afternoon. Dash might take a day or two. A Flask or Django app with a proper front end can take weeks.
Summary of the differences
Point
Streamlit
Flask
Django
Dash
Gradio
Main purpose
Data apps and internal tools
Light web apps and APIs
Full web products
Analytical dashboards
ML model demos
UI written in
Python
HTML, CSS, JS
HTML, CSS, JS
Python
Python
How updates happen
Whole script reruns
Request and response
Request and response
Callbacks
Function per event
Time to learn basics
Hours
Days
Weeks
Days
Hours
Design control
Low to medium
Full
Full
Medium to high
Low
Login and database
Basic login, no database layer
Through add-ons
Built in
Add-ons or enterprise
Simple password only
Heavy traffic
Needs extra setup
Yes
Yes
Yes
Limited
Free hosting
Community Cloud
None official
None official
None official
Hugging Face Spaces
Best fit
Dashboards, ML and AI tools, prototypes
APIs, custom sites
SaaS, portals, marketplaces
Complex linked charts
Quick model sharing
A short way to read this table: pick Streamlit when speed and simplicity matter most, Dash when you need a heavier dashboard, Gradio for a model demo, and Flask or Django when you are building a real product for the public.
How to turn Python scripts into web applications with Streamlit
Let's walk through a realistic example. Say you have a script that predicts which customers might cancel their subscription. Right now it reads a CSV from your laptop, runs a saved model and prints a list. The goal is to let the customer success team use it on their own.
Step 1: Split the script into small functions
Put each job in its own function: load data, clean it, load the model, predict. This makes caching and debugging easier.
Step 2: Install Streamlit
Run pip install streamlit inside your project's virtual environment. Check that it works with streamlit hello, which opens a small demo app.
Step 3: Swap fixed values for widgets
Anywhere your script has a fixed file path or number, replace it with a widget. The file path becomes st.file_uploader. A fixed risk threshold of 0.7 becomes a slider.
import streamlit as st
import pandas as pd
import joblib
FEATURES = ["tenure", "monthly_spend", "support_tickets"]
Replace print statements with tables, charts and st.metric numbers. Add st.download_button so the team can take the flagged list into their own tools.
Step 5: Cache the slow parts and tidy the layout
Wrap data loading in st.cache_data and the model in st.cache_resource, or the model reloads every time someone touches the slider. Then move settings into the sidebar and keep the main screen focused on the answer.
Step 6: Try to break it
Upload an empty file. Upload a file with a missing column. Upload a PDF renamed to end in .csv. All of these will happen in real use, so handle them now.
Step 7: Deploy
Push the code to GitHub, add a requirements.txt file, and deploy on Streamlit Community Cloud, your company's cloud account, or inside Snowflake if your data already lives there.
Where do the "hours" actually go?
The title of this guide says hours, not minutes. Here is a realistic split for a script that already works on your machine:
Task
Rough time
Tidying the script into functions
30 to 60 minutes
Adding widgets and outputs
45 to 90 minutes
Caching and layout
About 30 minutes
Testing with bad inputs and fixing errors
1 to 2 hours
Deployment and access setup
30 to 60 minutes
That adds up to half a day to a full day. Testing takes the biggest share, and it should. A demo that works once is easy. An app that behaves with real users takes more care.
Pro tip
Make the first version answer one question well. You can add pages later. Apps that try to do everything on the first screen are usually the ones people stop opening after a week.
Streamlit for machine learning applications
Machine learning is where Streamlit found its first fans, and it is still the most common reason people pick it up. Streamlit for machine learning applications makes sense for a simple reason: the people who build models already work in Python, and the people who need the results usually don't.
Model demos: Instead of a slide full of accuracy numbers, give stakeholders a screen where they can enter inputs and watch the prediction change. People trust what they can test for themselves.
What-if analysis: Sliders let a pricing manager test a 5 percent price rise and see predicted demand change on the spot.
Data labeling and review: Small teams build review screens where experts check model outputs and mark them right or wrong.
Model monitoring: Comparing this week's predictions with last month's shows when a model starts to drift.
Show confidence, not just the answer
One habit separates useful ML apps from pretty demos: showing how sure the model is. A "will cancel" prediction means very different things at 51 percent and at 97 percent. Show the probability, flag low-confidence cases, and if you can, add a simple chart of which inputs pushed the prediction up or down. Libraries like SHAP produce these charts, and Streamlit can display them directly.
prob = model.predict_proba(row)[0, 1]
st.metric("Churn probability", f"{prob:.0%}")
if 0.4 < prob < 0.6:
st.warning("The model is unsure about this customer. Please review manually.")
This small check tells people when to trust the app and when to look closer. Teams that use Streamlit for machine learning applications daily tend to add it early, usually after someone acts on a shaky prediction.
AI web application development with Streamlit
The rise of large language models brought Streamlit a second wave of users. Many teams now use it as the front end for chatbots, document question-and-answer tools and internal assistants. In early-stage AI web application development, it saves you from building a chat interface from scratch.
A basic chat app needs a place to type, a way to show messages and a memory of the conversation. Streamlit covers all three.
Here get_llm_reply stands for whatever function calls your model provider. st.write_stream shows the reply as it arrives, word by word, which makes the app feel faster even when the model needs several seconds.
A few practical points for AI apps:
• Keep API keys in st.secrets or environment variables, never in code you push to GitHub.
• Limit message length and the number of requests per session. One user pasting a huge document over and over can run up a real bill.
• Log questions and answers, within your privacy rules and with user consent, so you can see where the assistant gets things wrong.
For many teams, Streamlit is the right tool for the first stage of AI web application development: proving the idea works and learning what users really ask. If it grows into a customer-facing service with thousands of users, the logic often moves to a separate back-end API. That is a normal growth path.
When real data gets messy
Demo apps run on clean sample files. Real apps run on whatever people upload and whatever the database sends back. This is where most Streamlit apps succeed or fall apart.
Data gaps
Missing data shows up as empty cells, absent columns, date ranges with no records, or an API that returns nothing because a partner system is down.
The worst thing an app can do is quietly fill the gap and show a confident result. A sales chart with a missing week looks like a sudden drop, and people act on that dip.
Some habits that help:
• Check for required columns right after upload, and stop with a clear message if any are missing.
• Count missing values and show the count. "212 of 5,000 rows have no region" is honest and useful.
• Show gaps on charts as gaps. Don't join points across missing dates unless you label that you did.
• Let users choose how to treat missing values (drop the rows, fill with an average or keep them as "unknown") when the choice changes the result.
missing = [c for c in required if c not in df.columns]
if missing:
st.error(f"This file is missing: {', '.join(missing)}")
st.stop()
gaps = int(df[required].isna().sum().sum())
if gaps:
st.warning(f"{gaps} empty values found. Those rows are left out of the results.")
df = df.dropna(subset=required)
Conflicting signals
Sometimes the data isn't missing. It disagrees with itself. The CRM says a customer is active, but billing says their last payment failed. A model says a transaction is safe, while a rule-based check says it looks like fraud. Two regional reports show different revenue totals because one counts refunds and the other doesn't.
An app shouldn't hide this by silently picking one answer. A better approach is to show both values side by side and label where each one came from. People who know the business can often tell at a glance which is right.
It also helps to give conflicting records a clear "needs review" status, with a filter so users can see only those rows. And write down the rule you use to settle ties, such as "billing data wins over CRM for payment status," then show that rule in an expander on the page. When someone asks why the app says what it says, the answer is right there.
In Streamlit, st.columns handles side-by-side values and st.data_editor lets a reviewer pick the correct one.
Real-time decisions
Some apps support decisions that can't wait: warehouse stock levels, live delivery tracking, or alerts for unusual transactions. Because of the rerun model, a Streamlit page doesn't update by itself by default. It changes only when someone interacts with it.
For live data, use fragments. A function marked with @st.fragment(run_every="10s") reruns only that part of the page every ten seconds and leaves the rest alone.
@st.fragment(run_every="10s")
def live_orders():
data = fetch_latest_orders()
st.metric("Orders in the last hour", len(data))
st.caption(f"Updated at {pd.Timestamp.now():%H:%M:%S}")
live_orders()
Two things matter as much as speed. First, always show when the data was last updated. A number that stopped refreshing ten minutes ago looks exactly like a fresh one unless you say so. Second, match the cache time to the decision. st.cache_data(ttl=60) keeps data for 60 seconds, which is fine for a sales dashboard but too slow for a fraud alert, where you might skip caching and fetch fresh data every time.
If a decision has to happen in milliseconds, like blocking a suspicious payment, that logic belongs in a back-end service. Streamlit is the place to show the decision and let a person act on it.
Exceptions and errors
Databases time out, users type letters into number fields, models get inputs they never saw in training. By default, Streamlit shows the full Python error on the page. That helps while building, but in front of users it confuses people and can reveal internal details.
A cleaner setup looks like this:
• Wrap risky steps (reading files, calling APIs, running predictions) in try and except blocks, and show a friendly st.error message that says what went wrong and what to do next.
• Log the real error to a file or monitoring tool so developers can fix it later.
• Turn off detailed error messages in production by setting showErrorDetails = false under [client] in .streamlit/config.toml.
• Use st.stop() to end the run cleanly when a required input is missing, instead of letting the script crash further down.
• Use st.status or st.spinner for slow steps, so people know the app is working and hasn't frozen.
try:
result = call_pricing_api(product_id)
except TimeoutError:
st.error("The pricing service is slow right now. Please try again in a minute.")
logger.exception("Pricing API timeout")
st.stop()
Pro tip
Keep a small folder of "bad" test files: empty CSVs, odd text encodings, extra columns, dates in strange formats. Run them through the app before every release. It takes five minutes and catches most of the embarrassing bugs.
How the app behaves under load
Each open browser tab gets its own session on the server, with its own session state and its own run of your script. Ten users means ten copies of the script running. If each run takes three seconds of heavy computing, the server gets busy quickly. A few things follow from that:
• Memory grows with users. Large dataframes stored in session state are kept separately for each person. Store shared data through caching instead, which keeps one copy for everyone.
• Shared resources must be safe to share. Anything in st.cache_resource is used by all sessions at once. A model that is only read from is usually fine. An object that changes its own internal state while in use can mix up results between users.
• Long tasks block that user's session. If a report takes two minutes to build, the user stares at a spinner for two minutes. Move long jobs to a background worker or job queue and let the app check back for the result.
• Running several copies needs sticky sessions. Streamlit keeps a live WebSocket connection for each user. If you run multiple copies behind a load balancer, each user has to keep talking to the same copy, or their session resets.
As a loose guide, a well-cached app on a modest server handles dozens of active users easily. For a few hundred at once, plan hosting and background jobs carefully. For thousands, consider a different setup.
Limits worth knowing before you commit
These trade-offs catch people off guard:
• Design options are basic. Themes help, but a truly custom look needs CSS workarounds or custom components.
• The rerun model can surprise beginners. A button returns True only during the single run right after it is clicked. Session state fixes this, but it adds some complexity.
• Multi-step workflows with many user roles get messy fast.
• There is no built-in database layer. You connect to your own database with st.connection or regular Python libraries.
• Search engines don't index Streamlit pages well, so it isn't a good choice for public marketing pages.
None of these hurt internal tools and prototypes, which is what Streamlit was built for.
Getting your app in front of people
Streamlit Community Cloud is free and connects straight to a GitHub repository, which suits demos and small teams. Streamlit in Snowflake runs the app next to your data, with Snowflake handling access. For full control, package the app in a Docker container and run it on AWS, Google Cloud, Azure or your own servers.
For internal tools, put the app behind your company's login. Recent Streamlit versions include st.login, which works with identity providers such as Google or Microsoft through OpenID Connect.
Key takeaways
• Streamlit turns ordinary Python scripts into web apps without HTML, CSS or JavaScript.
• The whole script reruns on every interaction. Caching and session state keep it fast and remember what users did.
• Teams that need internal tools quickly can build Python web apps with Streamlit in a day or less.
• Dash suits complex dashboards, Gradio suits quick model demos, and Flask or Django suit full public products.
• Real apps need care around missing data, conflicting sources, live updates, errors and many users at once.
• Knowing how to turn Python scripts into web applications with Streamlit is a practical skill for any data, ML or AI team.
Where to go from here
Streamlit fills a gap that stayed open for years: the space between a Python script that works on one laptop and a full web product built by a separate team. For internal tools, model demos and the early stages of AI web application development, it is often the quickest route from an idea to something people can actually use.
Start small. Pick one script your team already depends on, add a few widgets and share it. Then test it with messy files, watch how people use it and improve it from there. If the app later outgrows Streamlit, you will have a working prototype and real user feedback to guide the next build. And if your team wants to build Python web apps with Streamlit but doesn't have the time in-house, working with an experienced AI development partner for the first version can get you there faster.
Nikhil Patel, our dynamic Director, charts our course with innovative fervor and strategic acumen. With a sharp eye for opportunity, he steers our company's ascent with resolute determination. Nikhil's empathetic leadership unites us, igniting a collective drive for greatness and propelling us toward boundless success.
Frequently Asked Questions
Yes. The library is open source under the Apache 2.0 license, so you can use it in commercial projects at no cost. Streamlit Community Cloud also lets you host apps for free, with some resource limits. You only pay if you host on your own cloud servers or run it inside Snowflake, where normal Snowflake usage charges apply.
No. You write everything in Python. Some people add a little CSS later or write custom components in JavaScript, but neither is needed for a useful app.
Yes, for the right kind of app. Many companies run internal tools on it daily. The key is good caching, proper error handling, a login in front of the app and hosting sized for your users. High-traffic public products are usually better served by Django or a separate front end.
It is one of its strongest uses. Streamlit for machine learning applications covers model demos, what-if tools, data labeling screens and monitoring dashboards. It works with scikit-learn, PyTorch, TensorFlow and Hugging Face models.
If you are comfortable with Python, you can build your first simple app in under an hour and a useful internal tool in a day. Getting comfortable with reruns, caching and session state usually takes a week or two of regular use.