FastAPI Template Review 2026: Python SaaS Starter
TL;DR
The FastAPI full-stack template (by Tiangolo/FastAPI) is the definitive Python SaaS foundation. Built by FastAPI's creator, it's production-quality with SQLModel, Alembic migrations, React frontend, Docker, and CI/CD. Free and MIT licensed. Best for Python/ML teams building SaaS who don't want to switch to Node.js.
What You Get
Source: github.com/fastapi/full-stack-fastapi-template
Core features:
- FastAPI + Python 3.12+
- Frontend: React + TypeScript (Vite)
- Database: PostgreSQL via SQLModel + Alembic
- Auth: JWT + OAuth2 password flow
- Email: Emails via SMTP/Mailgun
- Docker Compose for local development
- Docker/Kubernetes for production
- CI/CD: GitHub Actions
- Testing: pytest setup
- Auto-generated API docs (OpenAPI/Swagger)
- Free / MIT licensed
The FastAPI Advantage
FastAPI's automatic API documentation is a significant differentiator:
# main.py — FastAPI with auto-documentation
from fastapi import FastAPI, Depends, HTTPException
from sqlmodel import Session, select
from app.api.deps import get_current_user, get_db
from app.models import User, Item
app = FastAPI(
title="Your SaaS",
description="API documentation automatically generated",
version="1.0.0",
)
@app.get("/api/v1/items/", response_model=list[Item])
async def read_items(
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db),
skip: int = 0,
limit: int = 100,
) -> list[Item]:
"""Get all items for the current user."""
items = db.exec(
select(Item)
.where(Item.owner_id == current_user.id)
.offset(skip)
.limit(limit)
).all()
return items
Every decorated endpoint automatically generates:
- OpenAPI schema at
/docs - ReDoc API documentation at
/redoc - Type-safe TypeScript client generation (openapi-typescript-codegen)
Data Models with SQLModel
SQLModel unifies Pydantic validation with SQLAlchemy ORM:
# models.py — single model definition for API + database
from sqlmodel import SQLModel, Field, Relationship
from pydantic import EmailStr
from typing import Optional
import uuid
class UserBase(SQLModel):
email: EmailStr = Field(unique=True, index=True, max_length=255)
is_active: bool = True
is_superuser: bool = False
full_name: Optional[str] = Field(default=None, max_length=255)
class User(UserBase, table=True):
"""Database model"""
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
hashed_password: str
items: list["Item"] = Relationship(back_populates="owner")
class UserCreate(UserBase):
"""API input model"""
password: str = Field(min_length=8, max_length=40)
class UserPublic(UserBase):
"""API output model (no password)"""
id: uuid.UUID
class UserUpdate(SQLModel):
"""Partial update model"""
email: Optional[EmailStr] = None
full_name: Optional[str] = None
password: Optional[str] = None
This pattern eliminates the duplication between validation models and database models common in Django or raw SQLAlchemy.
Authentication
# security.py — JWT auth implementation
from datetime import datetime, timedelta
from jose import jwt, JWTError
from passlib.context import CryptContext
from app.core.config import settings
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
def create_access_token(subject: str) -> str:
expire = datetime.utcnow() + timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
to_encode = {"exp": expire, "sub": str(subject)}
return jwt.encode(to_encode, settings.SECRET_KEY, algorithm="HS256")
def verify_password(plain_password: str, hashed_password: str) -> bool:
return pwd_context.verify(plain_password, hashed_password)
# deps.py — reusable auth dependency
async def get_current_user(
token: str = Depends(oauth2_scheme),
db: Session = Depends(get_db)
) -> User:
try:
payload = jwt.decode(token, settings.SECRET_KEY, algorithms=["HS256"])
user_id = payload.get("sub")
except JWTError:
raise HTTPException(status_code=401, detail="Invalid credentials")
user = db.get(User, user_id)
if not user or not user.is_active:
raise HTTPException(status_code=401, detail="Inactive user")
return user
Adding Stripe
The template doesn't include Stripe, but the pattern is clean:
# api/v1/billing.py
import stripe
from fastapi import APIRouter, Depends
from app.api.deps import get_current_user
from app.core.config import settings
router = APIRouter()
stripe.api_key = settings.STRIPE_SECRET_KEY
@router.post("/create-checkout-session")
async def create_checkout_session(
price_id: str,
current_user: User = Depends(get_current_user),
):
session = stripe.checkout.Session.create(
customer_email=current_user.email,
line_items=[{"price": price_id, "quantity": 1}],
mode="subscription",
success_url=f"{settings.FRONTEND_URL}/dashboard?success=true",
cancel_url=f"{settings.FRONTEND_URL}/pricing",
metadata={"user_id": str(current_user.id)},
)
return {"url": session.url}
@router.post("/webhook")
async def stripe_webhook(request: Request):
payload = await request.body()
sig_header = request.headers.get("stripe-signature")
event = stripe.Webhook.construct_event(
payload, sig_header, settings.STRIPE_WEBHOOK_SECRET
)
if event["type"] == "checkout.session.completed":
user_id = event["data"]["object"]["metadata"]["user_id"]
await activate_subscription(user_id)
return {"status": "ok"}
Python vs Node.js for SaaS
| Factor | FastAPI (Python) | Node.js (Next.js) |
|---|---|---|
| AI/ML integration | Excellent | Possible but harder |
| NPM ecosystem | Limited | Extensive |
| Auto API docs | Built-in | External (Swagger-UI) |
| Type safety | Pydantic + mypy | TypeScript |
| Database ORM | SQLModel/SQLAlchemy | Prisma/Drizzle |
| Team familiarity | Python devs | JS/TS devs |
| Boilerplate ecosystem | Smaller | Large |
Choose FastAPI template when:
- Your team is Python-first
- AI/ML is a core product feature (seamless Hugging Face, PyTorch integration)
- You want built-in OpenAPI documentation
- Data processing pipelines are central to the product
Limitations
- Stripe not included — Must add yourself
- Frontend is basic React SPA — No SSR (Vite, not Next.js)
- Community size — Smaller than Node.js boilerplate community
- More DevOps required — Separate API + frontend deployment
- No blog/marketing pages — Pure application framework
Who Should Use FastAPI Template
Good fit:
- Python/data science teams building SaaS
- AI-powered products (RAG, ML inference, data pipelines)
- Teams building APIs with multiple frontend clients
- Products needing auto-generated API documentation
- Developers who know Python and don't want to learn Node.js
Bad fit:
- JavaScript-first teams
- Teams needing comprehensive SaaS features out of the box
- Products requiring SSR/SEO from the frontend (use Next.js)
Final Verdict
Rating: 4/5 for Python-first SaaS teams
The FastAPI full-stack template is the best starting point for Python-based SaaS. The SQLModel integration, automatic API docs, and clean architecture are production-quality. The absence of Stripe and blog features requires more setup vs Node.js alternatives. For Python teams, it's an easy recommendation — for JavaScript teams, stick with Next.js boilerplates.
Getting Started
# Clone the official template
git clone https://github.com/fastapi/full-stack-fastapi-template my-app
cd my-app
# Copy environment configuration
cp .env.example .env
# Configure DATABASE_URL, SECRET_KEY, FIRST_SUPERUSER_*
# Start with Docker Compose (recommended)
docker compose up -d
# Backend: http://localhost:8000
# Frontend: http://localhost:5173
# API docs: http://localhost:8000/docs
Docker Compose starts PostgreSQL, the FastAPI backend, and the React frontend together. Local development requires Docker but avoids manual database setup. The auto-generated API documentation at /docs is immediately usable for frontend development and API testing.
Celery for Background Tasks
FastAPI's async handlers work for fast requests, but long-running tasks need Celery:
# tasks.py — Celery tasks (add alongside FastAPI)
from celery import Celery
from app.core.config import settings
celery_app = Celery(
"worker",
broker=settings.CELERY_BROKER_URL, # Redis
backend=settings.CELERY_RESULT_BACKEND,
)
@celery_app.task
def process_report(user_id: str, report_type: str):
"""Long-running task — doesn't block the API."""
data = fetch_user_data(user_id)
report = generate_report(data, report_type)
upload_to_s3(report)
notify_user(user_id, report.url)
# api/v1/reports.py — API endpoint queues the task
@router.post("/reports/generate")
async def generate_report(
report_type: str,
current_user: User = Depends(get_current_user),
):
task = process_report.delay(str(current_user.id), report_type)
return {"task_id": task.id, "status": "queued"}
Add celery[redis] to requirements.txt and deploy the Celery worker as a separate Docker container. The FastAPI template's Docker Compose setup makes this a one-service addition.
Production Deployment
# docker-compose.prod.yml — production configuration
services:
backend:
image: my-fastapi-app:latest
environment:
- DATABASE_URL=${DATABASE_URL}
- SECRET_KEY=${SECRET_KEY}
command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4
frontend:
image: my-react-app:latest
# Served via nginx or Vercel
worker:
image: my-fastapi-app:latest
command: celery -A app.celery worker --loglevel=info
Railway and Render both support multi-service Docker Compose deployments. The FastAPI backend and Celery worker deploy as separate services sharing a PostgreSQL database. Frontend can deploy to Vercel independently — the API lives at your backend URL.
Key Takeaways
- FastAPI template is the definitive Python SaaS foundation — built by FastAPI's creator, free, MIT licensed, and production-quality
- Auto-generated OpenAPI docs at
/docsare a genuine differentiator for API-first products with multiple clients - SQLModel unifies validation (Pydantic) and ORM (SQLAlchemy) — no duplicated model definitions
- Stripe is not included; the billing pattern is straightforward to add given FastAPI's clean dependency injection
- Best for Python/data science teams — seamlessly integrates ML models, data pipelines, and Python scientific libraries
- JavaScript teams should use Next.js boilerplates; the Python ecosystem's SaaS tooling is smaller but improving
- The template is maintained by FastAPI's core team, which means it tracks major FastAPI releases reliably — this maintenance backing matters for a foundation you'll build a business on
- For AI-powered SaaS products in 2026, FastAPI's Python foundation enables seamless LangChain, LlamaIndex, and HuggingFace integrations without the wrapper libraries that Node.js AI SDKs require
- FastAPI's async-first design handles concurrent API requests efficiently; for data-intensive endpoints (ML inference, report generation), the async patterns outperform Django's default synchronous request handling
- The frontend is a basic React SPA (Vite, not Next.js) — teams that need SSR or SEO-optimized pages should pair FastAPI with Next.js as the frontend, connected via the auto-generated TypeScript API client
- Alembic database migrations are configured out of the box — a significant advantage over raw SQLAlchemy setups that require manually writing migration scripts; the pattern mirrors Prisma's migration workflow familiar to Node.js developers
FastAPI for AI-Powered SaaS
In 2026, FastAPI's most compelling use case is AI-powered SaaS. The Python ML ecosystem — PyTorch, Hugging Face Transformers, LangChain, LlamaIndex, scikit-learn — integrates directly into FastAPI endpoints without any interoperability layer. Node.js AI SDKs (Vercel AI SDK, LangChainJS) are mature and capable, but they wrap Python libraries at their core and introduce additional abstraction layers; calling ML models directly from Python eliminates that overhead and gives you direct access to the full model configuration surface area.
The typical pattern for AI SaaS on FastAPI:
The frontend (React SPA or Next.js) handles user interface and calls the FastAPI backend via the auto-generated TypeScript client. The FastAPI backend handles auth, billing webhooks, and routes to AI processing. The AI processing (inference, RAG pipeline, data analysis) runs either in the same FastAPI process for fast models or in Celery workers for heavier tasks. PostgreSQL stores structured application data; a vector database (Pinecone, Qdrant, or pgvector) stores embeddings.
This architecture handles most AI SaaS use cases: document Q&A, recommendation systems, classification pipelines, and custom model inference. The React frontend stays thin and handles UI concerns; the Python backend owns all the intelligence and can be updated, retrained, or swapped for different models without touching the frontend. This separation of concerns is architecturally clean and gives teams the ability to iterate on the AI components independently from the user interface.
For teams building AI SaaS who are debating Python vs TypeScript: the FastAPI + Next.js split is the most common architecture for AI-heavy products that also need a polished frontend. It's more operational complexity (two services, two deployments) but delivers better AI performance and developer experience for Python-first teams.
FastAPI vs Django for SaaS in 2026
Django and FastAPI serve overlapping use cases, but they make different tradeoffs that matter for SaaS products specifically.
Django's strengths for SaaS are its admin panel, ORM, and convention-based structure. Django admin + djaodjin gives you a working multi-tenant subscription SaaS faster than FastAPI if you need billing and multi-tenancy from day one. Django's ORM is more expressive for complex relational queries than SQLModel. For teams building traditional SaaS — subscription management, teams, permissions, content management — Django + djaodjin is the faster path.
FastAPI's strengths are async performance, automatic API documentation, and Python type safety with Pydantic. For products where the backend is primarily a JSON API (versus server-rendered HTML), FastAPI's request throughput is noticeably better than Django REST Framework at equivalent concurrency. For SaaS with an API-first architecture or significant ML processing, FastAPI's async model handles concurrent requests more efficiently.
The practical choice in 2026: use Django + djaodjin if you need billing and multi-tenancy immediately with minimal setup, value Django's built-in admin panel for operations, or are building a traditional web application with server-rendered pages. Use FastAPI template if your product is API-first or AI-heavy, you're comfortable adding Stripe yourself, or you want automatic OpenAPI documentation and async performance from day one.
Neither framework is better in absolute terms — the right choice depends on your team's existing expertise, the product's core technical requirements, and how much time you're willing to spend on initial configuration versus inheriting conventions. Teams that have shipped Django applications before will reach revenue faster with Django; teams with FastAPI experience or strong ML requirements will find FastAPI the more productive foundation. FastAPI's position has strengthened in 2025 as AI-heavy SaaS products have proliferated — the Python-native path to ML inference is increasingly the deciding factor for teams building products where intelligence is the core value.
See our djaodjin review for the Django alternative with built-in billing and multi-tenancy.
Browse best free open source SaaS boilerplates for the full open source comparison including Wasp and T3 Stack.
Compare Python and JavaScript SaaS starters in our best SaaS boilerplates 2026 roundup.
Check out this boilerplate
View FastAPI Templateon StarterPick →