{"id":205,"library":"starlette","title":"Starlette","description":"Lightweight ASGI framework and toolkit. Foundation for FastAPI. Released version 1.0.0 on Mar 22, 2026 — first stable release after 8 years on ZeroVer (0.x). Now follows SemVer. 1.0 removed all features deprecated during the 0.x era. Directly used by the Python MCP SDK.","status":"active","version":"1.0.0","language":"python","source_language":"en","source_url":"https://starlette.dev/release-notes/","tags":["web","asgi","framework","async","fastapi","routing","middleware"],"install":[{"cmd":"pip install starlette","lang":"bash","label":"Core"},{"cmd":"pip install \"starlette[full]\"","lang":"bash","label":"With all optional extras (jinja2, python-multipart, httpx, itsdangerous, pyyaml)"}],"dependencies":[{"reason":"Async runtime abstraction. Required, installed automatically.","package":"anyio>=3.4.0,<5","optional":false},{"reason":"Required for Jinja2Templates. NOT auto-installed. Import now fails at import time if missing (changed in 1.0).","package":"jinja2","optional":true},{"reason":"Required for form data and file uploads.","package":"python-multipart>=0.0.7","optional":true},{"reason":"Required for TestClient. Replaced requests in 0.20.0.","package":"httpx","optional":true},{"reason":"Required for SessionMiddleware.","package":"itsdangerous","optional":true}],"imports":[{"note":"on_startup and on_shutdown parameters removed in 1.0. The lifespan context manager is the only supported pattern.","wrong":"app = Starlette(\n    on_startup=[startup_handler],\n    on_shutdown=[shutdown_handler]\n)  # on_startup/on_shutdown removed in 1.0","symbol":"lifespan","correct":"from contextlib import asynccontextmanager\nfrom starlette.applications import Starlette\n\n@asynccontextmanager\nasync def lifespan(app):\n    # startup\n    yield\n    # shutdown\n\napp = Starlette(lifespan=lifespan)"},{"note":"@app.route() and @app.websocket_route() decorators removed in 1.0. Use declarative Route() objects in the routes list.","wrong":"@app.route('/')\nasync def homepage(request):\n    ...  # @app.route() decorator removed in 1.0","symbol":"Route (declarative)","correct":"from starlette.applications import Starlette\nfrom starlette.routing import Route\n\nasync def homepage(request):\n    ...\n\napp = Starlette(routes=[Route('/', homepage)])"}],"quickstart":{"code":"from contextlib import asynccontextmanager\nfrom starlette.applications import Starlette\nfrom starlette.requests import Request\nfrom starlette.responses import JSONResponse\nfrom starlette.routing import Route\n\n@asynccontextmanager\nasync def lifespan(app):\n    # startup logic\n    yield\n    # shutdown logic\n\nasync def homepage(request: Request):\n    return JSONResponse({'hello': 'world'})\n\napp = Starlette(\n    routes=[Route('/', homepage)],\n    lifespan=lifespan,\n)\n\n# Run: uvicorn main:app","lang":"python","description":"Minimal Starlette 1.0 app with lifespan and declarative routing."},"warnings":[{"fix":"Use lifespan context manager: @asynccontextmanager async def lifespan(app): yield — pass as app = Starlette(lifespan=lifespan).","message":"on_startup= and on_shutdown= parameters removed in 1.0. add_event_handler() also removed. All three were the primary patterns in older tutorials and LLM-generated code.","severity":"breaking","affected_versions":">= 1.0.0"},{"fix":"Use declarative routing: Starlette(routes=[Route('/', handler), WebSocketRoute('/ws', ws_handler)]).","message":"@app.route() and @app.websocket_route() decorators removed in 1.0. Were deprecated since 0.23.0 but widely used in tutorials for years.","severity":"breaking","affected_versions":">= 1.0.0"},{"fix":"pip install jinja2 or pip install 'starlette[full]'","message":"Jinja2Templates now raises ImportError at import time if jinja2 is not installed. Previously only raised when instantiating the class.","severity":"breaking","affected_versions":">= 1.0.0"},{"fix":"Mark trusted HTML strings with Markup() from markupsafe, or pass autoescape=False to Jinja2Templates() to restore old behavior.","message":"Jinja2Templates now enables autoescape by default. Templates that relied on unescaped output (e.g. rendering HTML strings) will now escape them.","severity":"breaking","affected_versions":">= 1.0.0"},{"fix":"pip install httpx. Use httpx response API — most methods are compatible. Use the bump-testclient migration tool for larger test suites.","message":"TestClient now uses httpx instead of requests (changed in 0.20.0). Test suites using requests-specific APIs on TestClient responses will break.","severity":"breaking","affected_versions":">= 0.20.0"},{"fix":"Upgrade Python to 3.10+. Pin starlette<1.0 to remain on Python 3.8/3.9.","message":"Python 3.8 and 3.9 support dropped. Starlette 1.0 requires Python >=3.10.","severity":"breaking","affected_versions":">= 1.0.0"},{"fix":"Let FastAPI manage the starlette version. Only pin starlette directly if using it standalone without FastAPI.","message":"Starlette is typically a transitive dependency via FastAPI — do not pin starlette version directly. FastAPI manages its own compatible Starlette range. Pinning starlette independently can cause conflicts.","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T10:10:53.968Z","next_check":"2026-06-25T00:00:00.000Z","problems":[],"ecosystem":"pypi","meta_description":null,"install_score":80,"install_tag":"verified","quickstart_score":80,"quickstart_tag":"verified","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"full","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0.1,"disk_size":"26.2M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0.1,"disk_size":"20.7M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"full","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0.1,"disk_size":"27M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0.1,"disk_size":"21M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"full","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0.1,"disk_size":"29.1M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0.1,"disk_size":"22.7M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"full","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0.1,"disk_size":"30M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0.1,"disk_size":"23M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"full","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0.1,"disk_size":"20.8M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0.1,"disk_size":"14.5M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"full","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0.1,"disk_size":"22M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0.1,"disk_size":"15M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"full","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0.3,"disk_size":"20.1M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0.3,"disk_size":"13.8M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"full","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0.1,"disk_size":"21M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0.1,"disk_size":"14M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"full","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0.1,"disk_size":"25.5M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0.1,"disk_size":"20.0M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"full","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0.1,"disk_size":"27M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0.1,"disk_size":"21M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"verified","tag_description":"quickstart runs on critical runtimes, recently tested","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}