When you first start with FastAPI, it’s tempting to throw everything into a single file — and it works fine… until your app grows. Then suddenly, your codebase becomes spaghetti.
In this post, we’ll go through how to structure a FastAPI project properly, using clean architecture principles that scale easily.
🚀 Why Project Structure Matters
A good structure makes your project:
- Easier to maintain and scale.
- Easier for new developers to understand.
- Ready for testing, CI/CD, and deployment.
If your FastAPI project looks like this:
main.py
models.py
routes.py
schemas.py
database.py
…it’s time for an upgrade.
🏗️ Recommended Folder Structure
Here’s a clean, production-ready structure I use for real projects:
app/...
When you first start with FastAPI, it’s tempting to throw everything into a single file — and it works fine… until your app grows. Then suddenly, your codebase becomes spaghetti.
In this post, we’ll go through how to structure a FastAPI project properly, using clean architecture principles that scale easily.
🚀 Why Project Structure Matters
A good structure makes your project:
- Easier to maintain and scale.
- Easier for new developers to understand.
- Ready for testing, CI/CD, and deployment.
If your FastAPI project looks like this:
main.py
models.py
routes.py
schemas.py
database.py
…it’s time for an upgrade.
🏗️ Recommended Folder Structure
Here’s a clean, production-ready structure I use for real projects:
app/
├── api/
│ ├── routes/
│ │ ├── users.py
│ │ ├── items.py
│ │ └── __init__.py
│ ├── deps.py
│ ├── __init__.py
│ └── api_v1.py
├── core/
│ ├── config.py
│ ├── security.py
│ └── __init__.py
├── db/
│ ├── base.py
│ ├── session.py
│ └── __init__.py
├── models/
│ ├── user.py
│ ├── item.py
│ └── __init__.py
├── schemas/
│ ├── user.py
│ ├── item.py
│ └── __init__.py
├── services/
│ ├── user_service.py
│ └── __init__.py
├── main.py
└── __init__.py
⚙️ Let’s Break It Down
core/
Contains global configurations — environment variables, security settings, and constants.
# app/core/config.py
from pydantic import BaseSettings
class Settings(BaseSettings):
APP_NAME: str = "My FastAPI App"
DATABASE_URL: str
class Config:
env_file = ".env"
settings = Settings()
db/
Handles all database setup — connection, session management, and base models.
# app/db/session.py
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from app.core.config import settings
engine = create_engine(settings.DATABASE_URL)
SessionLocal = sessionmaker(bind=engine, autocommit=False, autoflush=False)
api/routes/
Organize endpoints by domain — one file per feature.
# app/api/routes/users.py
from fastapi import APIRouter, Depends
from app.schemas.user import User
from app.services.user_service import get_all_users
router = APIRouter(prefix="/users", tags=["users"])
@router.get("/", response_model=list[User])
async def list_users():
return await get_all_users()
services/
Business logic lives here — keep it separate from routes.
# app/services/user_service.py
from app.db.session import SessionLocal
from app.models.user import User
async def get_all_users():
db = SessionLocal()
return db.query(User).all()
main.py
The entry point that ties everything together.
# app/main.py
from fastapi import FastAPI
from app.api.api_v1 import api_router
from app.core.config import settings
app = FastAPI(title=settings.APP_NAME)
app.include_router(api_router)
🧠 Tips for Scalable FastAPI Projects
✅ Use Pydantic models for input/output validation
✅ Split logic into layers — routes, services, models
✅ Use dependency injection for clean imports
✅ Add logging early — don’t debug with print()
✅ Separate environment variables from code
🧰 Example Repository
I’ve uploaded an example of this structure here: 👉 GitHub - fastapi-clean-structure (insert your repo link)
You can clone it, install dependencies, and start your app in seconds:
git clone https://github.com/yourusername/fastapi-clean-structure.git
cd fastapi-clean-structure
poetry install
poetry run uvicorn app.main:app --reload
🔚 Conclusion
Clean project structure isn’t just about being “organized” — it’s about future-proofing your codebase. FastAPI makes things fast, but structure makes them sustainable.
If you found this useful, drop a ❤️ or follow me — I post about Python, FastAPI, and backend architecture regularly.