Cloud Parts

Starlette

A small ASGI toolkit for Python: routing, requests and responses, middleware, WebSockets and a test client, usable as a whole framework or piece by piece, and the base FastAPI is built on.

What it is
API frameworks (http api frameworks)
Type
Open source
Made by
Marcelo Trylesinski and contributors (created by Kim Christie)
License
BSD 3-Clause
Facts checked
9 October 2026

What it is

A Starlette app is an ASGI application. You pass it a routing table, a list of Route, WebSocketRoute and Mount entries, and each route points at an endpoint that takes a request and returns a response. Paths capture parameters in braces, and convertors such as {order_id:int}, float, uuid and path turn them into Python values. Mount nests a list of routes or a whole other ASGI app under a prefix, which is how static files, sub-applications and GraphQL servers attach. Around that sit middleware (CORS, GZip, sessions), background tasks, a lifespan hook for startup and shutdown, and a TestClient that calls the app in-process. Each component can be used on its own, and the docs pitch them as building blocks to share between ASGI frameworks.

Starlette parses and routes, but it doesn’t validate input, serialize models or generate API docs; that is what FastAPI adds on top. Endpoints can be async def or plain def: plain functions, synchronous background tasks and file handling run in a thread pool of 40 threads by default, shared with libraries such as FastAPI. Its only required dependency is AnyIO, which lets it run on asyncio or Trio. Version 1.0 (March 2026) removed the old decorator-style API (@app.route, on_startup) in favour of the routes, middleware and lifespan arguments, and the project now follows semantic versioning.

Why teams pick it

  • Small and focused: one required dependency (AnyIO), and components that work on their own in any ASGI app
  • WebSockets, background tasks, streaming responses, sessions and an in-process test client built in
  • The foundation of FastAPI and a dependency of the Python MCP SDK, so its routing and request handling are widely exercised
  • Stable API since 1.0 (March 2026), with semantic versioning from then on

Watch out for

  • No request validation, serialization or OpenAPI generation: you check await request.json() yourself, or use FastAPI
  • Plain def endpoints share a thread pool of 40 threads by default; blocking work beyond that waits, unless you raise the AnyIO limit
  • Version 1.0 removed @app.route, @app.middleware, on_startup and on_shutdown, so older tutorials and code need updating
  • Built-in GraphQL support was removed in 0.17.0 (2021); GraphQL now comes from third-party libraries such as Strawberry or Ariadne

The Starlette family

1 technologies built from or on Starlette

How it fits with other technologies

Routes, a mount and a path convertor, tested in-process · python

# pip install starlette httpx2
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Mount, Route
from starlette.testclient import TestClient

async def get_order(request):
    order_id = request.path_params["order_id"]  # already an int
    return JSONResponse({"id": order_id, "status": "paid"})

async def create_order(request):
    body = await request.json()  # parsing is built in; validation is up to you
    if not isinstance(body.get("quantity"), int) or body["quantity"] < 1:
        return JSONResponse({"error": "quantity must be a positive integer"}, status_code=400)
    return JSONResponse({"id": 43, **body}, status_code=201)

app = Starlette(routes=[
    Mount("/orders", routes=[
        Route("/", create_order, methods=["POST"]),
        Route("/{order_id:int}", get_order),
    ]),
])

client = TestClient(app)
print(client.get("/orders/42").json())                            # {'id': 42, 'status': 'paid'}
print(client.get("/orders/abc").status_code)                      # 404: the int convertor didn’t match
print(client.post("/orders/", json={"quantity": 0}).status_code)  # 400

See it in a real stack

No architecture uses Starlette yet. Drop it into the playground and wire it up yourself.Open playground →
Where it came from2018–2026

Python’s web interface standard, WSGI, is one synchronous call per request, which can’t hold a WebSocket open. ASGI replaced it with one asynchronous callable that exchanges messages, but in 2018 there were few frameworks built for it. Kim Christie, who had created Django REST Framework, the API framework APIStar and the ASGI server Uvicorn, stopped developing APIStar as a server and created Starlette in June 2018 as a lightweight ASGI framework and toolkit.

FastAPI, first released in December 2018, made Starlette its base: the FastAPI class subclasses Starlette. In June 2021, version 0.15.0 moved Starlette’s async internals onto AnyIO, which added Trio support, and deprecated the built-in GraphQLApp; 0.17.0 removed it that November, leaving GraphQL to libraries such as Strawberry, Ariadne and Graphene. Marcelo Trylesinski, who works at Pydantic, now maintains it, and the repository lives under Trylesinski’s GitHub account, Kludex.

After years of 0.x releases, the 1.0.0 release candidate in February 2026 removed every feature marked for removal, and 1.0.0 followed on March 22, 2026. Its maintainer called it a stability and versioning milestone, not a rewrite, and reported downloads of 325 million a month, up from 57 million a year earlier.

Why it’s built this way

A toolkit as well as a framework
Every piece is an ASGI component, so a response class, a middleware or the router can be reused in another ASGI framework. That modularity is how FastAPI could build on Starlette instead of reimplementing it.
Endpoints receive one request argument
Since 0.6.0, endpoints no longer take path parameters as keyword arguments; they read request.path_params. Unusual among Python frameworks, but every endpoint then has the same signature, which the release notes argue is more consistent all the way through.
AnyIO instead of asyncio directly
Moving the low-level async code onto AnyIO in 0.15.0 let the same Starlette app run on asyncio or Trio.
Leave validation and GraphQL to other libraries
Starlette stays small: request validation, serialization and docs live in FastAPI, and the built-in GraphQL support was dropped in favour of dedicated libraries.

Timeline

  1. 2018

    Created in June by Kim Christie

  2. 2018

    FastAPI 0.1.0, built on Starlette, released in December

  3. 2021

    0.15.0 in June moves onto AnyIO, adds Trio and deprecates built-in GraphQL

  4. 2021

    0.17.0 removes GraphQL support in November

  5. 2026

    1.0.0 release candidate in February removes deprecated APIs

  6. 2026

    Starlette 1.0.0 on March 22, at 325 million downloads a month

Sources9 · facts checked 9 October 2026

Improve this page on GitHub