Server Backends

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.

When to Use Flask, FastAPI, or Quart

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.

Dash with Flask

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

Dash with FastAPI

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

Basic Usage

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)

Using Your Own FastAPI Server

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

Mixing Dash with Other Frontends

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

Async Callbacks

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.

Async Endpoints

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)

Deploying an App That Uses FastAPI

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"}

Dash with Quart

To use a Quart backend with Dash, install the Dash Quart extra:

pip install "dash[quart]"

Basic Usage

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)

Using Your Own Quart Server

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

Deploying an App That Uses Quart

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.

Limitations