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
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
@fastdash
def 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, str with 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 |
update("output_x", chunk) inside the fn + stream=True |
LLM / token-by-token / progress |
| Notebook rendering |
@fastdash(mode="inline") |
Jupyter |
| Wrap a custom component |
Fastify(dcc.Slider(...), "value") |
Any Dash component |
Full examples for each: references/patterns.md.
Type hint → component quick reference
| Hint |
Component |
str |
Textarea |
int, float |
Number input |
bool |
Checkbox |
Literal["a", "b"] |
Dropdown |
Annotated[int, range(0, 100)] |
Slider |
list |
Multi-select |
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 (
# Inputs
Text, TextArea, PasswordInput,
NumberInput, Slider,
Switch, MultiSelect,
DateInput, DateRange, ColorInput,
Upload, UploadImage,
# Outputs
Graph, 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 component
depends_on, # cascading input default
from_step, # multi-step pipeline data threading
update, notify, # push partial results / toasts during streaming
dcc, 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 use FastDash(...).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 / exec contexts fall back to OUTPUT_1, OUTPUT_2. Pass output_labels=[...] to override.
Full list with reproducers: references/gotchas.md.
Decision tree
- User has one function, simple form →
@fastdash on 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() with from_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) → call
update(component_id, data) inside the function + stream=True on 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().
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.
Source: dkedar7/fast_dash — distributed by TomeVault.
1---2name: fast-dash3description: 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, or build a dashboard / form / wizard. Fast Dash infers UI components from type hints, so a well-typed function becomes an app with one decorator. Use when this capability is needed.4---56# Fast Dash78Fast 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.910## When to use this skill1112Use this skill when the user:13- has a Python function and wants a UI for it ("make this a web app", "add a form", "dashboard around this")14- is prototyping an ML / data / API tool and wants shareable interactivity15- needs cascading inputs, a multi-step wizard, or multiple tools in one app1617Do **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.1819## Install2021```bash22pip install fast-dash23```2425## The core pattern2627```python28from fast_dash import fastdash2930@fastdash31def greet(name: str = "world") -> str:32 return f"Hello, {name}!"3334# Serving on http://127.0.0.1:808035```3637That is the whole app. Open the URL, type a name, click **Run**.3839## How to approach a Fast Dash task40411. **Start from the user's function.** If they don't have one, write the smallest function that captures their intent.422. **Add type hints and defaults.** This is where the UI comes from — `int` → number input, `bool` → checkbox, `str` with a list default → dropdown, etc. See [references/components.md](references/components.md) for the full table.433. **Decorate with `@fastdash`.** For more control (tabbed multi-function apps, multi-step pipelines), use the `FastDash(...)` class directly.444. **Run and verify.** The decorator starts a server immediately on import. For notebooks, pass `mode="inline"`.4546## Common patterns4748| Pattern | Syntax | When |49|---|---|---|50| Single function | `@fastdash` | One tool, one form |51| Multiple outputs | `-> (Graph, Graph)` + `mosaic="AB"` | Dashboard with several plots |52| Cascading inputs | `state=depends_on("country", resolver)` | Dependent dropdowns |53| Multiple tools, one app | `FastDash([fn_a, fn_b], tab_titles=[...])` | Tabbed "apps" under one URL |54| Multi-step wizard | `FastDash(steps=[fn_a, fn_b, fn_c])` + `from_step(prev_fn)` | Pipeline UX, one panel at a time |55| Streaming outputs | `update("output_x", chunk)` inside the fn + `stream=True` | LLM / token-by-token / progress |56| Notebook rendering | `@fastdash(mode="inline")` | Jupyter |57| Wrap a custom component | `Fastify(dcc.Slider(...), "value")` | Any Dash component |5859Full examples for each: [references/patterns.md](references/patterns.md).6061## Type hint → component quick reference6263| Hint | Component |64|---|---|65| `str` | Textarea |66| `int`, `float` | Number input |67| `bool` | Checkbox |68| `Literal["a", "b"]` | Dropdown |69| `Annotated[int, range(0, 100)]` | Slider |70| `list` | Multi-select |71| `datetime.date` | Date picker |72| `pd.DataFrame` (return) | Table |73| `plotly.graph_objects.Figure` (return) | Plotly chart |74| `PIL.Image.Image` | Image upload / display |7576Full table with every supported hint: [references/components.md](references/components.md).7778## Built-in components to import7980Pass these directly as `inputs=` or `outputs=` when you want to override inference:8182```python83from fast_dash import (84 # Inputs85 Text, TextArea, PasswordInput,86 NumberInput, Slider,87 Switch, MultiSelect,88 DateInput, DateRange, ColorInput,89 Upload, UploadImage,90 # Outputs91 Graph, Image, Table, Markdown, Chat, Download,92)93```9495For streaming and building custom UIs, also available:9697```python98from fast_dash import (99 Fastify, # wrap any Dash component as a Fast Dash component100 depends_on, # cascading input default101 from_step, # multi-step pipeline data threading102 update, notify, # push partial results / toasts during streaming103 dcc, dbc, dmc, html, # re-exported: dash.dcc, dash_bootstrap_components, dash_mantine_components, dash.html104)105```106107## Non-obvious things that will bite you108109- **`@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 use `FastDash(...).run()`.110- **Default Bootswatch `theme=` does not restyle Mantine chrome** (v0.2.x). Only dark/light flips for known dark themes (`CYBORG`, `DARKLY`, `SLATE`, ...).111- **Don't reuse a single component instance across inputs and outputs** — pass the class (`inputs=Text`) not an instance. Mutation surprises.112- **Output labels come from the `return` line of the source.** REPL / `exec` contexts fall back to `OUTPUT_1`, `OUTPUT_2`. Pass `output_labels=[...]` to override.113114Full list with reproducers: [references/gotchas.md](references/gotchas.md).115116## Decision tree117118- User has **one function, simple form** → `@fastdash` on the function, done.119- User has **one function, multiple outputs** → `@fastdash(mosaic="AB\nAC")`, return a tuple of components.120- User has **multiple independent tools** → `FastDash([fn_a, fn_b], tab_titles=[...]).run()`.121- User has **a pipeline (step 1 output feeds step 2)** → `FastDash(steps=[fn_a, fn_b, ...]).run()` with `from_step(prev_fn)` defaults.122- User has **dependent dropdowns** → `depends_on("parent_name", resolver)` as a default value.123- User wants **streaming / token-by-token output** (LLMs, progress) → call `update(component_id, data)` inside the function + `stream=True` on the app.124- User wants the app **in a Jupyter notebook** → add `mode="inline"`.125- User wants to **not start the server immediately** → use `FastDash(...)` class, skip `.run()`.126127## Before reporting complete128129Run the app and verify it loads. If you can't open a browser:130- check the console for tracebacks131- confirm the port (default `8080`) is free132- for notebooks, confirm `mode="inline"` was set133134If the user has dash[testing] installed, a headless smoke test is worthwhile. Otherwise, ask the user to verify the UI themselves.135136---137> Source: [dkedar7/fast_dash](https://github.com/dkedar7/fast_dash) — distributed by [TomeVault](https://tomevault.io).138<!-- tomevault:4.0:skill_md:2026-07-01 -->