Skill v1.0.1
currentAutomated scan100/100+4 new
name: fast-dash description: Build a Fast Dash web app from a Python function. Use when the user wants to turn a function into an interactive app, add a UI to an existing function, build a dashboard / form / wizard, add a chat assistant to an app, or make an app that AI agents can drive over MCP. Fast Dash infers UI components from type hints, so a well-typed function becomes an app with one decorator. metadata: version: "1.0.1"
Fast Dash
Fast Dash turns a Python function into a Plotly Dash web app. The @fastdash decorator reads the function's signature, maps each parameter's type hint to a UI component, maps the return type to an output component, and serves the result. No frontend, no callbacks, no boilerplate.
When to use this skill
Use this skill when the user:
- has a Python function and wants a UI for it ("make this a web app", "add a form", "dashboard around this")
- is prototyping an ML / data / API tool and wants shareable interactivity
- needs cascading inputs, a multi-step wizard, or multiple tools in one app
- wants an AI agent (Claude Code, Cursor, ...) to drive the app over MCP, or a chat assistant beside it
Do not use this for: production apps with complex routing, custom auth, or non-Python frontends — Fast Dash is opinionated for the single-file-Python-function use case.
Install
pip install fast-dash
The core pattern
from fast_dash import fastdash@fastdashdef greet(name: str = "world") -> str:return f"Hello, {name}!"# Serving on http://127.0.0.1:8080
That is the whole app. Open the URL, type a name, click Run.
How to approach a Fast Dash task
- Start from the user's function. If they don't have one, write the smallest function that captures their intent.
- Add type hints and defaults. This is where the UI comes from —
int→ number input,bool→ checkbox,strwith a list default → dropdown, etc. See references/components.md for the full table. - Decorate with `@fastdash`. For more control (tabbed multi-function apps, multi-step pipelines), use the
FastDash(...)class directly. - Run and verify. The decorator starts a server immediately on import. For notebooks, pass
mode="inline".
Common patterns
| Pattern | Syntax | When | |
|---|---|---|---|
| Single function | @fastdash | One tool, one form | |
| Multiple outputs | -> (Graph, Graph) + mosaic="AB" | Dashboard with several plots | |
| Cascading inputs | state=depends_on("country", resolver) | Dependent dropdowns | |
| Multiple tools, one app | FastDash([fn_a, fn_b], tab_titles=[...]) | Tabbed "apps" under one URL | |
| Multi-step wizard | FastDash(steps=[fn_a, fn_b, fn_c]) + from_step(prev_fn) | Pipeline UX, one panel at a time | |
| Streaming outputs | yield partial results (or update("x", chunk)) + stream=True | LLM / token-by-token / progress | |
| Notebook rendering | @fastdash(mode="inline") | Jupyter | |
| Wrap a custom component | Fastify(dcc.Slider(...), "value") | Any Dash component | |
| Drive from an AI agent | @fastdash(mcp_server=True) → agent connects to :8080/mcp | Human and agent use the same app | |
| Agent-built form | DynamicDash(callback_fn=..., mcp_server=True) + agent calls set_form | Form fields decided at runtime | |
| Chat assistant | @fastdash(chat=True) on a yield-ing function, or chat=True, chat_model=... on a normal app | Chat UI / assistant beside an app |
Full examples for each: references/patterns.md.
Type hint → component quick reference
| Hint | Component | |
|---|---|---|
str | Single-line text input (a long / multi-line default → text area) | |
str with default=[...] | Dropdown, starting on the first option | |
int, float | Number input | |
bool | Checkbox | |
Literal["a", "b"] | Dropdown | |
Annotated[int, range(0, 100)] | Slider | |
list | Multi-select (starts with nothing picked) | |
int with default=range(...) | Slider, starting at the range start | |
datetime.date | Date picker | |
pd.DataFrame (return) | Table | |
plotly.graph_objects.Figure (return) | Plotly chart | |
PIL.Image.Image | Image upload / display |
Full table with every supported hint: references/components.md.
Built-in components to import
Pass these directly as inputs= or outputs= when you want to override inference:
from fast_dash import (# InputsText, TextArea, PasswordInput,NumberInput, Slider,Switch, MultiSelect,DateInput, DateRange, ColorInput,Upload, UploadImage,# OutputsGraph, Image, Table, Markdown, Chat, Download,)
For streaming and building custom UIs, also available:
from fast_dash import (Fastify, # wrap any Dash component as a Fast Dash componentdepends_on, # cascading input defaultfrom_step, # multi-step pipeline data threadingupdate, notify, # push partial results / toasts during streamingdcc, dbc, dmc, html, # re-exported: dash.dcc, dash_bootstrap_components, dash_mantine_components, dash.html)
Non-obvious things that will bite you
- `@fastdash` starts the server on import. Put it in a
if __name__ == "__main__":guard if the file is imported elsewhere, or skip the decorator and useFastDash(...).run(). - Default Bootswatch `theme=` does not restyle Mantine chrome (v0.2.x). Only dark/light flips for known dark themes (
CYBORG,DARKLY,SLATE, ...). - Don't reuse a single component instance across inputs and outputs — pass the class (
inputs=Text) not an instance. Mutation surprises. - Output labels come from the `return` line of the source. REPL /
execcontexts fall back toOUTPUT_1,OUTPUT_2. Passoutput_labels=[...]to override.
Full list with reproducers: references/gotchas.md.
Decision tree
- User has one function, simple form →
@fastdashon the function, done. - User has one function, multiple outputs →
@fastdash(mosaic="AB\nAC"), return a tuple of components. - User has multiple independent tools →
FastDash([fn_a, fn_b], tab_titles=[...]).run(). - User has a pipeline (step 1 output feeds step 2) →
FastDash(steps=[fn_a, fn_b, ...]).run()withfrom_step(prev_fn)defaults. - User has dependent dropdowns →
depends_on("parent_name", resolver)as a default value. - User wants streaming / token-by-token output (LLMs, progress) →
yieldpartial results (or callupdate(name, data),name= the returned variable) +stream=Trueon the app. - User wants the app in a Jupyter notebook → add
mode="inline". - User wants to not start the server immediately → use
FastDash(...)class, skip.run(). - User wants an AI agent to use the app → add
mcp_server=True; the agent connects tohttp://localhost:8080/mcpand starts withdescribe_app(). Addbackend="fastapi"(needsfast-dash[fastapi]) for real-time push. - User wants the agent to decide the form →
DynamicDash(callback_fn=fn, placeholder=..., mcp_server=True); the agent callsset_form(specs=[...]). - User wants a chat assistant →
chat=True(see references/patterns.md); an auto-built assistant needspip install "fast-dash[agent]".
Before reporting complete
Run the app and verify it loads. If you can't open a browser:
- check the console for tracebacks
- confirm the port (default
8080) is free - for notebooks, confirm
mode="inline"was set
If the user has dash[testing] installed, a headless smoke test is worthwhile. Otherwise, ask the user to verify the UI themselves.