New in Dash 4.2
By default, when you initialize a Dash app, Dash creates a Flask server to handle requests, serve your app’s layout, and process callbacks. Dash also supports using FastAPI and Quart as backends. These alternative backends enable more performant async support and integration with their respective ecosystems. With any of these backends, you can also provide your own server, allowing you to integrate Dash into an existing web application.
Flask is the default backend for Dash. Choose Flask when:
- You want the simplest setup with no extra dependencies.
- Your app doesn’t need custom async endpoints, WebSockets, or server-sent events. Note that Flask also supports async callbacks with pip install "dash[async]" (see Advanced Callbacks).
- You’re integrating with an existing Flask application or Flask extensions.
- You’re deploying to Plotly Cloud and want the simplest deployment experience.
FastAPI is a modern, high-performance ASGI framework. Choose FastAPI when:
- You need async endpoints, WebSockets, or server-sent events alongside your Dash app.
- You’re building a project that combines Dash with a REST or WebSocket API.
- You’re already using FastAPI or want to leverage its dependency injection system.
- You want automatic interactive API documentation (available at /docs).
Quart is an async version of Flask’s API. Choose Quart when:
- You want async capabilities but prefer Flask’s API style and conventions.
- You’re migrating an existing Dash app which leverages the Flask API and want minimal code changes.
- You need WebSockets or server-sent events but want to stay in the Flask ecosystem.
All three backends support Dash callbacks, layouts, and core features identically. The difference is in what you can do with custom server-side endpoints.
By default, when you use the following Dash constructor, Dash internally creates a Flask server.
from dash import Dash, html
app = Dash()
app.layout = html.Div("Hello Dash!")
if __name__ == "__main__":
app.run(debug=True)
Dash can also use an existing Flask server, allowing you to embed a Dash app at a specific route in an existing Flask app. In the following example, a Dash app is mounted at the /dash route.
from flask import Flask
from dash import Dash, html
server = Flask(__name__)
@server.route('/')
def index():
return 'Hello Flask app'
app = Dash(
server=server,
routes_pathname_prefix='/dash/'
)
app.layout = html.Div("My Dash app")
if __name__ == '__main__':
app.run(debug=True)
Now your server handles:
- / → your Flask route (“Hello Flask app”)
- /dash/ → your Dash app
To use a FastAPI backend with Dash, install the Dash FastAPI extra:
pip install "dash[fastapi]"
When using a FastAPI backend, you can run your app with app.run() during development, just like with Flask. When providing your own FastAPI server or deploying to production, run it with uvicorn directly:
uvicorn app:server --host 0.0.0.0 --port 8050
You can configure Dash to create a FastAPI server to use as a backend by setting backend="fastapi" on the Dash constructor.
from dash import Dash, html
app = Dash(backend="fastapi")
server = app.server
app.layout = html.Div("Hello Dash with FastAPI!")
if __name__ == "__main__":
app.run(debug=True)
You can also provide an existing FastAPI server to Dash. This allows you to add FastAPI routes alongside your Dash app:
from fastapi import FastAPI
from dash import Dash, html
server = FastAPI()
@server.get("/api/hello")
def hello():
return {"message": "Hello from FastAPI"}
app = Dash(server=server)
app.layout = html.Div("My Dash app with FastAPI")
if __name__ == "__main__":
app.run(debug=True)
Now your server handles:
- / → your Dash app
- /api/hello → your FastAPI route
You can serve a Dash app alongside a React app (or any static site) from the same FastAPI server, with shared API endpoints accessible to both:
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
from dash import Dash, html, dcc
server = FastAPI()
# Mount Dash app at /dashboard/
# Dash automatically detects the backend when given a server.
app = Dash(server=server, routes_pathname_prefix="/dashboard/")
app.layout = html.Div([
html.H1("Dash Dashboard"),
dcc.Graph(figure={"data": [{"x": [1, 2, 3], "y": [4, 1, 2], "type": "bar"}]})
])
# Shared API endpoints used by both frontends
@server.get("/api/data")
def get_data():
return {"values": [1, 2, 3, 4, 5]}
# Serve a React (or any static) app at /app/
server.mount("/app", StaticFiles(directory="react_build", html=True), name="react")
if __name__ == "__main__":
import uvicorn
uvicorn.run(server, host="0.0.0.0", port=8050)
Now your server handles:
- /dashboard/ → your Dash app
- /app/ → your React app (served as static files from react_build/)
- /api/data → a shared API endpoint available to both frontends
When using a FastAPI backend, your Dash callbacks can use async def natively without any extra dependencies. See Using Async/Await in Callbacks for more details.
You can also define asynchronous custom endpoints directly on app.server:
from dash import Dash, html
app = Dash(backend="fastapi")
@app.server.get("/api/data")
async def get_data():
"""An async endpoint alongside your Dash app."""
return {
"status": "success",
"message": "Hello from an async FastAPI endpoint!",
}
app.layout = html.Div("My Dash app with an async FastAPI endpoint")
if __name__ == "__main__":
app.run(debug=True)
When deploying to Plotly Cloud, your backend is detected automatically, so no additional configuration is required.
To deploy a Dash app that uses FastAPI to Dash Enterprise, add dash[fastapi] and uvicorn[standard] to your requirements.txt. The standard extra includes WebSocket support, which is required for WebSocket callbacks:
dash[fastapi]
uvicorn[standard]
And add a Procfile to run the app with uvicorn, specifying --host 0.0.0.0 --port 8000:
web: uvicorn <module>:<server> --host 0.0.0.0 --port 8000
Where <module> is the name of your Python file (e.g., app for app.py) and <server> is the FastAPI server variable.
If your app has custom FastAPI routes, they need to include the DASH_ROUTES_PATHNAME_PREFIX environment variable. On Dash Enterprise, apps are served at a subpath like /your-app-name/, and this prefix must be included in your route paths:
import os
prefix = os.environ.get("DASH_ROUTES_PATHNAME_PREFIX", "/")
@server.get(f"{prefix}api/hello")
def hello():
return {"message": "Hello from FastAPI"}
To use a Quart backend with Dash, install the Dash Quart extra:
pip install "dash[quart]"
You can configure Dash to create a Quart server to use as a backend by setting backend="quart" on the Dash constructor.
from dash import Dash, html
app = Dash(backend="quart")
server = app.server
app.layout = html.Div("Hello Dash with Quart!")
if __name__ == "__main__":
app.run(debug=True)
You can also provide an existing Quart server to Dash. This allows you to add Quart routes alongside your Dash app:
from quart import Quart
from dash import Dash, html
server = Quart(__name__)
@server.route("/api/hello")
async def api_hello():
return {"message": "Hello from Quart"}
app = Dash(server=server)
app.layout = html.Div("My Dash app with Quart")
if __name__ == "__main__":
app.run(debug=True)
Now your server handles:
- / → your Dash app
- /api/hello → your Quart route
When deploying to Plotly Cloud, your backend is detected automatically, so no additional configuration is required.
To deploy a Dash app that uses Quart to Dash Enterprise, add dash[quart] and uvicorn[standard] to your requirements.txt. The standard extra includes WebSocket support, which is required for WebSocket callbacks:
dash[quart]
uvicorn[standard]
And add a Procfile to run the app with uvicorn, specifying --host 0.0.0.0 --port 8000:
web: uvicorn <module>:<server> --host 0.0.0.0 --port 8000
Where <module> is the name of your Python file (e.g., app for app.py) and <server> is the Quart server variable.
If your app has custom Quart routes, they need to include the DASH_ROUTES_PATHNAME_PREFIX environment variable. On Dash Enterprise, apps are served at a subpath like /your-app-name/, and this prefix must be included in your route paths.
dash-embedded, dash-chatbot-builder, and dash-snapshots.