Introduction
Over the last ten years, the world of Python, especially for building websites and APIs, has changed a lot. Back in the day, tools like Flask and Django were the go-to choices, but they worked in a step-by-step, "one thing at a time" way. Now, developers have lots of options, including newer tools that can handle many tasks at once, which is great for building big, fast systems.
But with so many choices, it’s harder to pick the right one. You want something that’s fast, can grow with your project, and is actually enjoyable to use, not something that makes your life more complicated.
As apps need to do more in real time, like handling lots of users at once, managing data quickly, and running multiple tasks simultaneously, a new standard called ASGI has popped up. Frameworks built on ASGI can handle thousands of users at the same time, support live updates, and work well with other modern tools. These are all must-haves for today’s web apps.
That’s where Litestar comes in. It’s a modern, lightweight, and flexible framework designed to make building fast APIs easier. Litestar manages to be both powerful and user-friendly: it’s quick and efficient, but also makes coding feel smooth, safe, and straightforward.
What Is Litestar?
Litestar is a modern Python tool for building APIs and web apps. It’s built on ASGI, which is a fancy way of saying it’s designed to handle lots of tasks at the same time, like managing many users or running multiple processes without slowing down.
Litestar actually started as a small project called Starlite, inspired by other tools like Starlette and FastAPI. But as it grew, it became much more than just a simple experiment. Now, it’s a full-featured, flexible tool that’s great for building serious, scalable backends.
The idea behind Litestar is simple:
Keep it light, but don’t skimp on features.
So, it’s fast and doesn’t get in your way, but it still has everything you’d need for a professional project: automatic checks for your data, built-in documentation, easy ways to manage dependencies, and support for things like databases, caching, and background tasks.
Litestar is built from the ground up to handle async tasks, meaning it’s great for things like real-time updates or managing lots of users at once. But unlike some other async tools that can feel clunky or overly technical, Litestar uses Python’s type hints to make coding feel natural and intuitive. You can define your API endpoints with clear types, and the framework takes care of checking your data, organizing it, and even generating documentation for you.
Key Features
Litestar is designed to give developers the perfect mix of simplicity, flexibility, and power. It has everything you need to build robust, professional APIs, without making your life harder. Let’s break down what makes it special.
Type Hints for Easy Request Handling
Litestar uses Python’s type hints to make handling requests straightforward. You just define what kind of data your function expects and what it returns, and Litestar takes care of the rest, checking the data, organizing it, and even creating documentation for you. No extra work or manual checks needed; your type hints do the job.
Routing & Controllers: Two Ways to Organize Your Code
Litestar lets you define routes in two simple ways: as standalone functions or as part of a class (called a controller). This makes it easy to keep things tidy, whether you’re working on a small project or a big, complex system.
Behind the scenes, Litestar organizes things in layers:
App → Router → Controller → Function
This setup makes it easy to group related routes, share resources, and manage extra features (like security or logging) at different levels.
Dependency Injection & Middleware: Keep Things Clean and Reusable
Litestar has a built-in system for managing dependencies, meaning you can easily share and reuse things like database connections or settings across your app. You just declare what you need in your function, and Litestar handles the rest. This keeps your code clean and easy to test.
It also supports middleware and lifecycle hooks, so you can run code automatically at key moments, like when your app starts up, shuts down, or processes a request. This is useful for things like:
- Setting up database connections when the app starts
- Cleaning up resources when the app closes
- Adding security, logging, or rate limiting for each request
Automatic API Documentation
Litestar automatically creates up-to-date API documentation based on your code and type hints. You don’t have to write anything extra, it just works. Once your app is running, you can check out:
-
Swagger UI (a user-friendly interface) at
/schema/swagger -
ReDoc (another documentation style) at
/schema/redoc -
Raw OpenAPI JSON (for machines) at
/schema/openapi.json
This means your API docs are always ready to share with your team or anyone else who needs them.
Database & Plugin Support
Litestar comes with built-in support for SQLAlchemy, a popular database tool. It handles all the setup for you, so you can focus on writing your app instead of dealing with boilerplate code. You can easily inject a database session into your functions without any hassle.
Beyond databases, Litestar’s plugin system lets you add extra features for things like:
- Caching with Redis
- Background task queues
- File storage
- Custom login systems
WebSockets, Streaming, and Background Tasks
Modern apps often need real-time features, like live updates or streaming data. Litestar makes these easy to implement. It also supports background tasks, so you can offload time-consuming jobs, like sending emails or processing data, without slowing down your app.
Building a CRUD API
Let’s try out Litestar by building a simple Todo List API. This is a classic example that shows just how easy it is to create a basic app where you can add, read, update, and delete tasks, all with minimal setup.
In this guide, we’ll use Litestar and SQLAlchemy (a tool for working with databases) and keep things simple by using SQLite, which doesn’t require any extra setup.
Getting Started
First, let’s install the tools we need:
pip install "litestar[standard]" "litestar[sqlalchemy]" sqlalchemy aiosqlite
This command installs everything we need:
- Litestar - the main tool for building our API
- SQLAlchemy - helps us work with the database easily
- aiosqlite - lets us use SQLite in a way that doesn’t block our app
Here’s how we’ll organize our project files:
todo_api/
│
├── app.py
├── models.py
└── routes.py
Creating the Todo Task Structure
Let’s define what a Todo task looks like in our app. We’ll use SQLAlchemy to set this up in a file called models.py. This is where we describe how our tasks are stored in the database, like what information each task has.
# models.py
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy import String, Boolean
from litestar.plugins.sqlalchemy import base
class TodoItem(base.UUIDBase):
__tablename__ = "todo_items"
title: Mapped[str] = mapped_column(String(100))
done: Mapped[bool] = mapped_column(Boolean, default=False)
This model describes a simple Todo task with just a few details:
- A title (what the task is about)
- A completion flag (whether it’s done or not)
- An ID (a unique identifier for each task, handled automatically by
base.UUIDBase)
Litestar and SQLAlchemy will take care of creating the database table and managing how we save or retrieve tasks, no extra work needed.
Setting Up the App
Now, let’s create the main part of our app in a file called app.py. Here, we’ll set up the Litestar app and tell it how to work with our database using the SQLAlchemy plugin.
# app.py
from litestar import Litestar
from litestar.plugins.sqlalchemy import AsyncSessionConfig, SQLAlchemyAsyncConfig, SQLAlchemyPlugin, base
from routes import routes
# SQLAlchemy configuration
session_config = AsyncSessionConfig(expire_on_commit=False)
sqlalchemy_config = SQLAlchemyAsyncConfig(
connection_string="sqlite+aiosqlite:///todo.db",
session_config=session_config,
create_all=True
)
# Initialize app
app = Litestar(
plugins=[SQLAlchemyPlugin(config=sqlalchemy_config)],
route_handlers=[routes]
)
The SQLAlchemyPlugin takes care of all the database setup for us:
- It handles how the app connects to the database and manages those connections.
- It automatically creates the tables we need when the app starts.
- It makes it easy to use the database in our code by providing a session whenever we need it.
Creating the API Endpoints
Now, let’s add the actual features of our app in a file called routes.py. Here, we’ll define how to:
- Create a new task
- Read (or list) all tasks
- Update a task
- Delete a task
We’ll use Litestar’s tools to keep our code clean and let the framework handle the database connections for us.
# routes.py
from litestar import get, post, put, delete, Router
from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from models import TodoItem
@post("/todos")
async def create_todo(data: TodoItem, db_session: AsyncSession, db_engine: AsyncEngine) -> TodoItem:
db_session.add(data)
await db_session.commit()
await db_session.refresh(data)
return data
@get("/todos")
async def list_todos(db_session: AsyncSession, db_engine: AsyncEngine) -> list[TodoItem]:
result = await db_session.execute(select(TodoItem))
return result.scalars().all()
@get("/todos/{todo_id:int}")
async def get_todo(todo_id: int, db_session: AsyncSession) -> TodoItem | None:
result = await db_session.execute(select(TodoItem).where(TodoItem.id == todo_id))
return result.scalar_one_or_none()
@put("/todos/{todo_id:int}")
async def update_todo(todo_id: int, data: TodoItem, db_session: AsyncSession, db_engine: AsyncEngine) -> TodoItem | None:
result = await db_session.execute(select(TodoItem).where(TodoItem.id == todo_id))
todo = result.scalar_one_or_none()
if not todo:
return None
todo.title = data.title
todo.done = data.done
await db_session.commit()
await db_session.refresh(todo)
return todo
@delete("/todos/{todo_id:int}")
async def delete_todo(todo_id: int, db_session: AsyncSession, db_engine: AsyncEngine) -> None:
result = await db_session.execute(select(TodoItem).where(TodoItem.id == todo_id))
todo = result.scalar_one_or_none()
if not todo:
from litestar.exceptions import NotFoundException
raise NotFoundException("Todo not found")
await db_session.delete(todo)
await db_session.commit()
# Group all routes under a router
routes = Router(path="/api", route_handlers=[create_todo, list_todos, get_todo, update_todo, delete_todo])
Here’s what happens in each part of our code:
- The database session is automatically available whenever we need it, no manual setup required.
- Litestar converts our database models into easy-to-read JSON responses.
- It checks the data we receive (like new tasks or updates) to make sure it’s correct, all based on the types we defined.
Starting and Trying Out the App
To get the app up and running, just use this command:
uvicorn app:app --reload
or
litestar run
Your app will start, and you’ll see Litestar running a server at this address: http://127.0.0.1:8000
Adding a New Task
curl -X POST http://127.0.0.1:8000/api/todos \
-H "Content-Type: application/json" \
-d '{"title": "Write Litestar article", "done": false}'
When you add a new task, you’ll get a response like this:
{"title":"Write Litestar article","done":false,"id":"9eab1384-487e-46be-9d4b-8f8fcdb81f46"}
Seeing All Your Tasks
To see a list of all your tasks, just run:
curl http://127.0.0.1:8000/api/todos
You’ll get a response like this:
[{"title":"Write Litestar article","done":false,"id":"9eab1384-487e-46be-9d4b-8f8fcdb81f46"}]
Exploring the API Documentation
Litestar also creates a user-friendly guide for your API automatically. You can check it out here: http://127.0.0.1:8000/schema/swagger
This page lets you try out your API right in the browser, no extra tools needed!
Full source code at: https://github.com/nunombispo/Litestar-Article
Comparing Litestar, FastAPI, and Flask
When picking a Python framework for building web apps or APIs, you’re usually balancing different needs, like how flexible it is, how fast it runs, and how easy it is to use. Litestar, FastAPI, and Flask each have their own strengths and fit different kinds of projects.
Litestar is like the next step in modern Python web frameworks. It’s built to be fast, flexible, and easy to use, giving you more control over performance and how you structure your data, without making things complicated.
Here’s how these three frameworks compare:
| Feature | Litestar | FastAPI | Flask |
|---|---|---|---|
| Async Support | Built-in, ready to go | Built-in, ready to go | Needs extra tools |
| Data Modeling | Lots of options (Pydantic, msgspec, etc.) | Only Pydantic | Manual or needs extra tools |
| Dependency Injection | Built-in, works with types | Built-in | Needs extra tools |
| Database Support | Easy setup with async SQLAlchemy | Manual setup | Manual setup |
| Speed | Very fast—optimized for performance | Fast—async and Pydantic-based | Slower—older, synchronous model |
| Community & Tools | Growing fast | Lots of tools and support | Huge plugin library |
What Does This Mean for You?
Litestar is a great choice if you want speed, flexibility, and modern features. It’s perfect for teams who want a fast, powerful framework but still want to keep their code clean and easy to manage. It’s like a more advanced, flexible version of FastAPI.
FastAPI is still the most popular option, especially if you want something easy to learn with lots of documentation and community support. It’s great for quickly building APIs, especially if you’re okay with using Pydantic for your data models.
Flask is reliable and has been around for a long time, but it’s starting to show its age. It’s still a solid choice for small projects or traditional apps, but it doesn’t have built-in support for modern features like async programming or type hints.
Which One Should You Pick?
If you want a modern, fast, and flexible framework that gives you more control and better performance, Litestar is the way to go. It’s like FastAPI but with more options and fewer limitations, ideal for developers who want to build powerful apps without being boxed in.
Wrapping Up
There are a lot of Python frameworks out there, but Litestar really stands out. It’s fast, powerful, and easy to use, a combination that’s hard to find. It gives you the speed you’d expect from a modern framework, but it also makes building APIs feel simple and intuitive.
Whether you’re creating a basic API, a real-time service with WebSockets, or a complex backend with a database, Litestar lets you design your app exactly how you want. It’s simple enough for quick projects but strong enough for serious, real-world applications.
If you like how easy FastAPI is to use, how fast Starlette runs, and the idea of adding extra features with plugins, Litestar is definitely worth trying. Give it a shot, set up a small project, play around with its features, and see how much you can do with just a little bit of code.
Follow me on Twitter: https://twitter.com/DevAsService
Follow me on Instagram: https://www.instagram.com/devasservice/
Follow me on TikTok: https://www.tiktok.com/@devasservice
Follow me on YouTube: https://www.youtube.com/@DevAsService
Top comments (0)