**[REQUIRED]** Use for ALL Streamlit tasks: creating, editing, debugging, beautifying, styling, theming, or optimizing Streamlit applications. Also required for building custom components (inline or packaged), using st.components.v2, or any HTML/JS/CSS component work. Triggers: streamlit, st., dashboard, app.py, beautify, style, CSS, color, background, theme, button, widget styling, custom component, st.components, packaged component, pyproject.toml, asset_dir, CCv2, HTML/JS component.
This is a routing skill that directs you to specialized references for Streamlit development.
Invoke this skill when the user's request involves:
Trigger phrases: "streamlit", "st.", "dashboard", "app.py", "beautify app", "make it look better", "style", "CSS", "color", "background", "theme", "button", "slow rerun", "session state", "performance", "faster", "cache"
Step 1: Locate the Streamlit source code
↓
Step 2: Identify task type and load appropriate reference(s)
↓
Step 3: Apply guidance from reference to edit code
↓
Step 4: Check if app is running and offer to run it
Goal: Identify the app file(s) to edit. Skip this step if already clear from context.
When to skip:
src/app.py")app.py, streamlit_app.py)When to search:
If searching is needed:
Quick scan for Streamlit files:
grep -rl 'import streamlit\|from streamlit' --include='*.py' . 2>/dev/null | head -10
Apply entry point heuristics (in priority order):
streamlit_app.py at root → this is the entry point (canonical name)app.py at root → likely entry pointst.navigation → entry point for multi-page apps.py file at root with streamlit import → entry pointpages/ or app_pages/ subdirectory → NOT entry points (these are sub-pages)If entry point is obvious → use it, no confirmation needed
Example: Found streamlit_app.py and pages/metrics.py → use streamlit_app.py
Only ask if genuinely ambiguous (e.g., multiple root-level candidates, none named streamlit_app.py):
Found multiple potential entry points:
- dashboard.py
- main.py
Which is your main app?
Output: Path to the main Streamlit source file(s)
Goal: Determine what the user needs and load the appropriate guidance.
IMPORTANT — use_container_width is deprecated. Never add use_container_width to new code. Streamlit elements now stretch to fill their container by default. Use width="stretch" or width="content" instead. Remove use_container_width when you encounter it.
Use this routing table to select reference(s). Always read the reference file before making changes.
All file paths below are relative to this skill's directory (
streamlit/.agents/skills/developing-with-streamlit/).
| User Need | Reference to Read |
|---|---|
App is slow, reruns take too long, or data loads repeatedly — caching strategies (st.cache_data, st.cache_resource), st.fragment for partial reruns, and avoiding unnecessary recomputation | read references/performance.md |
Building a dashboard with KPIs, metrics, and charts — composing st.metric, charts, and data tables into clean dashboard layouts with columns and containers | read references/dashboards.md |
| Making an app look polished — icons (Material Symbols), spacing, color accents, visual hierarchy, and small design touches that elevate quality | read references/design.md |
Choosing the right selection widget — when to use st.selectbox vs st.radio vs st.pills vs st.segmented_control vs st.multiselect, including modern replacements for deprecated patterns | read references/selection-widgets.md |
Custom themes, colors, and CSS styling — configuring colors in .streamlit/config.toml, reading the active theme at runtime via st.context.theme, and targeting widgets with st.markdown CSS injection | read references/theme.md |
Page structure and layout — st.columns, st.tabs, st.sidebar, st.container, st.expander, responsive layout patterns, and when to use each container type | read references/layouts.md |
Displaying or editing tabular data — st.dataframe column configuration, st.data_editor for editable tables, chart selection, and best practices for large datasets | read references/data-display.md |
Multi-page app architecture — st.navigation, st.Page, page routing, shared state across pages, and structuring apps with multiple views | read references/multipage-apps.md |
Persisting values across reruns — st.session_state, widget keys, callbacks (on_change, on_click), and patterns for stateful interactions | read references/session-state.md |
Rich text formatting — Markdown in st.markdown and widget labels, colored text (:red[...]), badges, Material Symbols icons (:material/icon_name:), and LaTeX math | read references/markdown.md |
Chat and conversational UIs — st.chat_message, st.chat_input, streaming responses with st.write_stream, and building AI assistant interfaces | read references/chat-ui.md |
Connecting to Snowflake — st.connection("snowflake"), secrets configuration, querying data, and Snowflake-specific patterns | read references/snowflake-connection.md |
| Building or packaging a custom component, triggering events back to Python from JS/HTML, custom HTML/JS with event handling (CCv2), OR any UI element that doesn't exist as a native Streamlit widget (e.g., drag-and-drop, custom interactive visualization, canvas drawing) | read references/custom-components-v2.md — IMPORTANT: st.components.v1 is deprecated. Never use v1 for new components; always use st.components.v2.component(). |
Using third-party community components — streamlit-extras (pagination, annotated text), streamlit-pivot-table, and other popular packages that extend Streamlit's built-in capabilities | read references/third-party-components.md |
| Structuring app code — when to split into modules vs keep in one file, helper functions, and clean project organization patterns | read references/code-organization.md |
| Environment and dependency setup — Python environment management, installing packages, and configuring the development environment for Streamlit apps | read references/environment-setup.md |
Streamlit CLI and configuration — streamlit run, streamlit config, .streamlit/config.toml (script-level and project-level), port settings, and server options | read references/cli.md |
Fallback — "this widget doesn't exist in Streamlit":
If the user asks for a UI element or interaction that has never been part of Streamlit's API and cannot be built with any combination of native widgets (e.g., drag-and-drop, canvas drawing, custom interactive visualizations), route to the CCv2 reference (references/custom-components-v2.md). Do not route to CCv2 for features that exist in newer Streamlit versions (e.g., st.connection, st.segmented_control) — suggest upgrading instead.
Common combinations:
For beautifying/improving an app, read in order:
references/design.mdreferences/layouts.mdreferences/selection-widgets.mdFor building a dashboard, read:
references/dashboards.mdreferences/data-display.mdFor performance optimization, read:
references/performance.mdGoal: Make changes to the Streamlit app following reference best practices.
Actions:
Goal: Help the user see their changes by checking if their app is running.
Actions:
Check for running Streamlit apps on ports 850*:
lsof -nP -iTCP -sTCP:LISTEN 2>/dev/null | grep -i python | awk '{print $2, $9}' | grep ':85' || echo "No Streamlit apps detected on ports 850*"
Present findings to user:
If app is running:
Found Streamlit app running:
- PID: [pid] at http://localhost:[port]
Your changes should be visible after a page refresh (Streamlit hot-reloads on file save).
If no app is running:
No Streamlit app detected on ports 850*.
Would you like me to run the app? I can start it with:
streamlit run [app_file.py]
If user wants to run the app, start it:
streamlit run [path/to/app.py] --server.port 8501