cheat sheet

litestar

Package-level reference for Litestar on PyPI — install variants, version policy, the `[full]` extra, ecosystem companions, and alternatives.

#pip#package#web#async#apiupdated 05-31-2026

litestar

What it is

litestar is an ASGI web framework (formerly named Starlite) maintained by the Litestar Organization, a community-led group that forked the project in 2023 to ensure broad-based governance. It pairs strict typing with native Pydantic v2, msgspec, and attrs support, and offers a richer DI container, plugin system, and OpenAPI generator than FastAPI — usually with lower per-route overhead.

Reach for Litestar when you want FastAPI-style ergonomics with stricter typing, a real plugin lifecycle, and significantly higher throughput on hot paths. Reach for FastAPI when the surrounding tutorials/SDKs assume it, or when you specifically want Pydantic-driven routes without msgspec.

Install

bash
pip install litestar

Output: (none — exits 0 on success)

bash
uv add litestar

Output: dependency resolved + added to pyproject.toml

bash
poetry add litestar

Output: updated lockfile + virtualenv install

bash
pip install "litestar[standard]"     # framework + uvicorn + jinja + structlog
pip install "litestar[full]"         # framework + every optional integration
pip install "litestar[sqlalchemy]"   # database plugin
pip install "litestar[redis]"        # redis store + caching
pip install "litestar[jwt]"          # jwt auth plugin

Output: Litestar plus the named bundle of optional integrations

Versioning & Python support

  • Current line is the 2.x series (as of mid-2026). Litestar 2.0 shipped after the project renamed from Starlite in 2023; the 1.x Starlite line is deprecated.
  • Supports Python 3.8+ on 2.x recent releases; 3.9+ on the newest minor lines.
  • Semver-aligned — breaking changes require a major bump. The 1.x → 2.x migration was significant; subsequent 2.x minor releases have stayed compatible.
  • Pydantic v1 is supported but deprecated; new projects should use Pydantic v2 or msgspec/attrs for DTOs.

Package metadata

  • Maintainer: The Litestar Organization
  • Project home: github.com/litestar-org/litestar
  • Docs: docs.litestar.dev
  • PyPI: pypi.org/project/litestar
  • License: MIT
  • Governance: community-led non-profit organization (the rename from Starlite codified shared maintainership)
  • First released: 2021 (as Starlite); renamed to Litestar in 2023
  • Downloads: millions per month — growing share of the async-Python API space

Optional dependencies & extras

  • litestar[standard] — sensible default bundle: uvicorn, jinja2, structlog, picologging, plus the litestar CLI.
  • litestar[full] — every optional integration: standard plus sqlalchemy, attrs, pydantic, msgspec, redis, jwt, cli, cryptography, and more.
  • litestar[sqlalchemy]advanced-alchemy plugin for SQLAlchemy 2.x integration.
  • litestar[redis]redis-py for the Redis store / pub-sub channels.
  • litestar[jwt]python-jose for JWT authentication helpers.
  • litestar[cli]click + rich for the litestar CLI command.
  • litestar[opentelemetry] — OTel instrumentation plugin.
  • litestar[prometheus] — Prometheus metrics middleware.
  • litestar[structlog] — structured logging plugin.

Common companion packages typically installed alongside:

  • uvicorn[standard] or granian — ASGI server (Granian is a Rust-backed alternative with high throughput)
  • msgspec — fastest path for DTOs / serialization
  • pydantic — when you specifically want Pydantic v2 models
  • advanced-alchemy — opinionated SQLAlchemy 2.x repository layer (by the Litestar maintainers)
  • httpx — for TestClient
  • structlog / picologging — structured logging backends
  • polyfactory — fixture / factory generation, also by the Litestar org

Alternatives

PackageTrade-off
fastapiLarger ecosystem and tutorial coverage; less strict typing. Use for default async Python REST.
starletteThe ASGI toolkit under FastAPI. Use for routing without validation/OpenAPI overhead.
flask + extensionsSync, WSGI, smaller surface. Use for non-async apps.
django + DRF/ninjaFull-stack. Use when you need admin/ORM batteries.
quartFlask-API-compatible but async. Use when migrating Flask code to async.
robyn / granian + raw ASGIRust-backed servers. Use when raw throughput dominates ecosystem maturity.

Common gotchas

  1. Renamed from Starlite — the import path is litestar, not starlite. If you find tutorials referencing from starlite import ..., they're targeting the deprecated 1.x line. Migrate to litestar.
  2. Pydantic v1 is deprecated in 2.x. It still works, but new code should use Pydantic v2, msgspec, or attrs for DTOs. The DI container handles all three transparently.
  3. DTOs are not Pydantic models. Litestar's DTO system is a separate abstraction over Pydantic / msgspec / attrs. Mixing route-annotated models and DTOs can produce confusing OpenAPI output — pick one style per app.
  4. [full] is heavy. Pulls in ~15 optional deps including SQLAlchemy and Redis clients. Prefer [standard] plus only the extras you need.
  5. The litestar CLI requires [cli] (or [standard]). Without it, litestar run and litestar routes don't exist on PATH.
  6. OpenAPI rendering picks Scalar by default. Litestar serves Scalar, Swagger UI, Redoc, Rapidoc, and Elements all at once at different sub-paths. If a consumer expects /docs to be Swagger UI, configure openapi_config=OpenAPIConfig(..., path="/docs", render_plugins=[SwaggerRenderPlugin()]).
  7. Plugin lifecycle vs middleware. Plugins integrate at app-build time (registering routes, DI providers, OpenAPI components); middleware runs per request. Putting cross-cutting setup in middleware that should be a plugin is a common modeling mistake.

Version migration guide

The major rename from Starlite to Litestar happened alongside the 1.x → 2.x API overhaul. Most apps need both a package change AND code-level adjustments. Subsequent 2.x minor releases have stayed compatible.

Starlite 1.x → Litestar 2.x:

bash
# Replace the dependency
pip uninstall starlite
pip install litestar

Output: old package removed; litestar installed with current deps.

python
# Before — Starlite 1.x
from starlite import Starlite, get, post, MediaType
from starlite.dto import DTOFactory
from starlite.connection import Request

@get("/items/{item_id:int}", media_type=MediaType.JSON)
async def get_item(item_id: int) -> dict: ...

app = Starlite(route_handlers=[get_item])
python
# After — Litestar 2.x
from litestar import Litestar, get, post, MediaType
from litestar.dto import DataclassDTO   # (or PydanticDTO, MsgspecDTO)
from litestar.connection import Request

@get("/items/{item_id:int}", media_type=MediaType.JSON)
async def get_item(item_id: int) -> dict: ...

app = Litestar(route_handlers=[get_item])

Output: module rename is mechanical; the DTO system is the part that requires real changes.

Other 2.x migration notes:

  • DTOFactoryDataclassDTO / PydanticDTO / MsgspecDTO (one base class per source format).
  • before_request / after_request hooks → middleware or before_request parameter on the app.
  • Logging config moved into LoggingConfig; pass via Litestar(logging_config=...).
  • OpenAPI config moved into OpenAPIConfig and gained render_plugins=[...] for picking the UI.
  • from starlite.testing import TestClientfrom litestar.testing import TestClient.
  • Channels API redesigned — Channel/ChannelsPlugin replace the older websocket-event hooks.

For long-running Starlite apps, the migration is usually a 1-2 day effort plus a careful diff of the OpenAPI output.

Production deployment

Litestar is ASGI — production is the same shape as FastAPI: pick a server (uvicorn, granian, hypercorn) and run it behind a reverse proxy. granian is the differentiator — a Rust-backed ASGI server that often outperforms uvicorn on throughput-bound workloads.

bash
# Recommended: granian (Rust runtime) for max throughput
pip install granian
granian --interface asgi myapp:app --host 0.0.0.0 --port 8000 --workers 4

Output: Rust-managed workers; typically 20-40% higher RPS than uvicorn on the same hardware.

bash
# uvicorn — most familiar choice
pip install "uvicorn[standard]"
uvicorn myapp:app --host 0.0.0.0 --port 8000 --workers 4 --proxy-headers

Output: standard ASGI server; equivalent to FastAPI's deployment pattern.

bash
# litestar CLI (requires litestar[standard] or [cli])
litestar --app myapp:app run --host 0.0.0.0 --port 8000 --reload  # dev

Output: dev server with auto-reload; not for prod.

python
# Lifespan hooks — replaces FastAPI's @app.on_event
from contextlib import asynccontextmanager
from litestar import Litestar

@asynccontextmanager
async def lifespan(app: Litestar):
    await db.connect()
    yield
    await db.disconnect()

app = Litestar(lifespan=[lifespan])

Output: on-startup and on-shutdown side effects wired in.

Granian configuration tip: pass --blocking-threads 1 --runtime-threads 1 for I/O-bound apps; raise both for CPU-mixed loads. Behind a load balancer, set --http2-keepalive-timeout and trust the LB to do TLS termination.

Real-world recipes

Concrete package-level patterns. The companion python/litestar.md covers handlers, DI, and DTOs; here we focus on plugin composition, msgspec hot paths, and structural choices unique to Litestar.

python
# Recipe 1 — msgspec DTOs for hottest paths
from litestar import Litestar, get
from litestar.dto import MsgspecDTO, DTOConfig
import msgspec

class User(msgspec.Struct):
    id: int
    name: str
    email: str

class UserReadDTO(MsgspecDTO[User]):
    config = DTOConfig(exclude={"email"})

@get("/users/{user_id:int}", return_dto=UserReadDTO)
async def get_user(user_id: int) -> User: ...

app = Litestar([get_user])

Output: email stripped on serialization; msgspec is roughly 5-10× faster than Pydantic for this shape.

python
# Recipe 2 — DI provider with caching
from litestar import Provide
from litestar.di import Provide

async def get_db_session() -> AsyncSession:
    async with SessionLocal() as s:
        yield s

app = Litestar(
    route_handlers=[...],
    dependencies={"db": Provide(get_db_session)},
)

Output: every route declaring db: AsyncSession gets a fresh scoped session.

python
# Recipe 3 — OpenAPI control: pick a UI and add servers
from litestar.openapi import OpenAPIConfig
from litestar.openapi.plugins import SwaggerRenderPlugin

openapi_config = OpenAPIConfig(
    title="My API",
    version="1.0.0",
    path="/docs",
    render_plugins=[SwaggerRenderPlugin()],
    servers=[{"url": "https://api.example.com"}],
)
app = Litestar(route_handlers=[...], openapi_config=openapi_config)

Output: Swagger UI at /docs; OpenAPI document at /docs/openapi.json.

python
# Recipe 4 — Channels (websockets pub/sub)
from litestar import Litestar
from litestar.channels import ChannelsPlugin
from litestar.channels.backends.memory import MemoryChannelsBackend

channels = ChannelsPlugin(
    backend=MemoryChannelsBackend(history=10),
    channels=["chat"],
)
app = Litestar([], plugins=[channels])

Output: in-memory channel with last-10-message history; swap for Redis backend for multi-process.

python
# Recipe 5 — JWT auth with the bundled plugin
from litestar.security.jwt import JWTAuth, Token

jwt_auth = JWTAuth[User](
    retrieve_user_handler=retrieve_user,
    token_secret=os.environ["JWT_SECRET"],
    exclude=["/login", "/docs", "/schema"],
)
app = Litestar([login_handler, ...], on_app_init=[jwt_auth.on_app_init])

Output: every non-excluded route requires a valid JWT.

Troubleshooting common errors

Error / SymptomLikely causeFix
ImportError: cannot import name '...' from 'starlite'Code still on the old nameRename imports to litestar; uninstall the old package.
ValidationException: ... on requestsDTO config mismatchVerify DTOConfig include/exclude and that the response type matches the DTO's source.
OpenAPI shows wrong schemaMixing inline Pydantic and DTOsStandardize on one — DTO-based handlers everywhere or annotation-based everywhere.
litestar CLI not foundMissing litestar[cli] or [standard]pip install "litestar[standard]".
Async DB session leaksProvider not using yield correctlyUse async def provider with yield so cleanup runs after the response.
Granian worker exits immediatelyWrong interface flag--interface asgi (not wsgi or rsgi).
pydantic.ValidationError not auto-handledCustom exception handler swallows itRemove the catch-all; Litestar maps Pydantic errors to 400 by default.
Channels never broadcastWrong backend or channel not declaredPre-declare in channels=[...]; switch to RedisChannelsBackend for multi-process.

Testing & CI integration

Litestar ships a TestClient (sync) and AsyncTestClient (async) — both wrap httpx and call the app in-process. For full DI/plugin coverage, use the app factory pattern so each test builds a fresh Litestar instance.

python
# pytest fixture for a fresh app per test
import pytest
from litestar import Litestar
from litestar.testing import TestClient

@pytest.fixture
def app():
    return Litestar(route_handlers=[my_handler])

@pytest.fixture
def client(app):
    with TestClient(app=app) as c:
        yield c

def test_get(client):
    r = client.get("/items/42")
    assert r.status_code == 200

Output: test passes; lifespan startup/shutdown fire inside the with block.

python
# Async test
import pytest
from litestar.testing import AsyncTestClient

@pytest.mark.asyncio
async def test_get_async(app):
    async with AsyncTestClient(app=app) as c:
        r = await c.get("/items/42")
    assert r.status_code == 200

Output: async-native; lifespan still wired.

python
# polyfactory for DTO fixtures
# pip install polyfactory
from polyfactory.factories.pydantic_factory import ModelFactory

class UserFactory(ModelFactory[User]):
    __model__ = User

user = UserFactory.build()   # auto-populated random instance

Output: fully-populated User; useful for hypothesis-style property tests.

When NOT to use this

Litestar is a strong choice for many APIs, but consider alternatives when:

  • You're already deep in the FastAPI ecosystem — tutorials, courses, and a larger SDK surface make it the safer default.
  • You need Django's admin + ORM — Litestar is API-first; pair Django + django-ninja instead.
  • Pure sync apps — Flask is simpler and well-trodden.
  • Hard pre-1.0-deps policy concerns — Litestar 2.x is stable but the project is newer than FastAPI. If "stable for a decade" matters more than throughput, weigh that.
  • Tiny single-route scriptsstarlette directly is even leaner.

See also