My first impressions using Django + Rust + msgspec
Today I jumped into something fresh and pretty exciting — Django’s new Rust-powered API framework, Django Bolt. Repo: https://github.com/FarhanAliRaza/django-bolt
This thing is aiming to bring FastAPI-like speed and async vibes into Django, and honestly… that alone is enough to hype any backend dev.
One cool part? Validation uses msgspec, which is written in C. So the framework already has a performance boost in its veins.
This post is just my first impression. If you already know the basics of Django, you can follow along smoothly.
🧱 Initial Setup
First, create a new project with uv:
uv init django-bolt-learn
cd django-bolt-learn
rm hello.pyInstall Django:
uv run django-admin startproject django-bolt-learn .This creates the Django project inside the current folder (no nested directory).
Next, install Django Bolt:
uv add django-boltAdd it to your Django settings:
INSTALLED_APPS = [
...
"django_bolt",
...
]Then create a new app for APIs:
uv run python manage.py startapp apisAdd "apis" to INSTALLED_APPS.
⚡ Creating Your First Bolt API
Create api.py either inside the main project folder or inside your new app.
from django_bolt import BoltAPI
api = BoltAPI()This is super similar to FastAPI — just create an instance and decorate your routes:
@api.get('/')
async def root():
return JSON({"message": "Hello, world!"})Run the Bolt server:
uv run python manage.py runbolt --devImportant: Your project must have an api.py file containing:
api = BoltAPI()Otherwise you’ll see:
No BoltAPI instances found. Create api.py files with api = BoltAPI()🛒 Building Basic CRUD – Products & Orders
Let's set up basic e-commerce models in apis/models.py:
from django.db import models
from django.contrib.auth.models import User
class Product(models.Model):
name = models.CharField(max_length=255)
description = models.TextField()
price = models.DecimalField(max_digits=10, decimal_places=2)
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='products')
def __str__(self):
return self.name
class Order(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
quantity = models.PositiveIntegerField()
price = models.DecimalField(max_digits=10, decimal_places=2)
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='orders')
def __str__(self):
return f"Order for {self.product.name} by {self.user.username}"For simplicity, I’m not using JWT here — just passing user_id in the payload.
📦 Schemas with msgspec
Create schemas.py:
import msgspec
class UserSchema(msgspec.Struct):
username: str
email: str
class ProductSchema(msgspec.Struct):
name: str
description: str
price: float
user_id: int
class ProductResponseSchema(ProductSchema):
id: int
user: UserSchema🧪 Product CRUD
Create Product
@api.post("/products", tags=["Product"])
async def create_product(product: ProductSchema) -> ProductResponseSchema:
try:
product = await Product.objects.acreate(
name=product.name,
description=product.description,
price=product.price,
user_id=product.user_id,
)
product = await Product.objects.prefetch_related("user").aget(id=product.id)
return ProductResponseSchema(
id=product.id,
name=product.name,
description=product.description,
price=product.price,
user_id=product.user_id,
user={"username": product.user.username, "email": product.user.email},
)
except Exception as e:
return JSON({"error": str(e)})Get All Products
@api.get("/products", tags=["Product"])
async def get_products() -> list[ProductResponseSchema]:
try:
products = await sync_to_async(list)(
Product.objects.select_related("user").all()
)
return [
ProductResponseSchema(
id=product.id,
name=product.name,
description=product.description,
price=product.price,
user_id=product.user_id,
user={"username": product.user.username, "email": product.user.email},
)
for product in products
]
except Exception as e:
return []Get Single Product
@api.get("/products/{product_id}", tags=["Product"])
async def get_product(product_id: int) -> ProductResponseSchema:
try:
product = await Product.objects.prefetch_related("user").aget(id=product_id)
return ProductResponseSchema(
id=product.id,
name=product.name,
description=product.description,
price=product.price,
user_id=product.user_id,
user={"username": product.user.username, "email": product.user.email},
)
except Exception as e:
return JSON({"error": str(e)})🛒 Order CRUD
Similar flow — create order, list user orders, get order by ID.
One important behavior:
If you don’t use select_related / prefetch_related, Bolt will throw an error because Django’s lazy loading tries to make sync DB calls inside async context.
This is actually good because:
- It avoids accidental N+1 queries
- Forces you into async-friendly query patterns
- Improves performance
- Similar behavior is seen in FastAPI + async SQLAlchemy
📜 Auto-Generated Swagger Docs
Visit:
/docsBolt automatically generates OpenAPI docs just like FastAPI. Makes testing super easy.
⚠ Notes & First Impressions
- Error handling with
return JSON({...})isn’t ideal — later I’ll explore a proper exception handler. - Framework is still incomplete, feature-wise.
- But the speed is honestly noticeable.
- The async + Rust combo feels refreshing inside Django.
- I’m liking it so far — will continue this Django Bolt series.
✨ Final Thoughts
Django Bolt feels like Django stepping into FastAPI’s territory — async-first, schema-driven, Rust-powered speed boosts, and developer-friendly API syntax.
Still early, still growing, but definitely something to keep an eye on.
More updates soon — I’ll keep pushing this series forward!
Jobi S S
admin
Sharing technical insights, engineering concepts, and practical modern software development guides.
Community Discussion
Enjoyed this read? Show your support or share your thoughts.




