( Compare )

NestJS vs FastAPI: how they structure a backend

NestJS and FastAPI solve different problems. NestJS is an opinionated TypeScript framework that prescribes how a backend is organised. FastAPI is a Python toolkit for typed, async APIs that leaves the structure up to you. Austial sits between them for Python teams: it keeps FastAPI underneath and adds NestJS-style structure.

The short answer

  • Choose NestJS if your team works in TypeScript and Node.js and wants a framework that decides the architecture for you.
  • Choose FastAPI if you want a light Python toolkit for typed, async APIs and are happy to decide the project structure yourself.
  • Choose Austial if you want Python and FastAPI but with NestJS-style modules, controllers, providers and dependency injection, usually because the codebase or the team is growing.
NestJS structure with FastAPI underneath: Austial adds modules, controllers, providers, guards, pipes and interceptors on top of FastAPI.
Austial keeps NestJS's structure and runs on FastAPI.

NestJS, FastAPI and Austial side by side

The columns are not rivals on every row. FastAPI is a toolkit and Austial is a framework built on it, so most of the differences are about how much structure is decided for you.

NestJS, FastAPI and Austial side by side
NestJSFastAPIAustial
LanguageTypeScript on Node.jsPythonPython 3.11 or newer
Built onExpress or FastifyStarlette and PydanticFastAPI
Project structureModules, controllers and providers are prescribedUp to you: routers and folders by conventionModules, controllers and providers are prescribed
Dependency injectionBuilt-in container, constructor injectionDepends() on function parametersBuilt-in container, constructor injection from type hints
ValidationPipes with class-validatorPydantic modelsPydantic models and a ValidationPipe
Request pipelineMiddleware, guards, interceptors, pipes, exception filtersMiddleware and dependenciesMiddleware, then guards, pipes, interceptors, handler, exception filters
API docsSwagger moduleOpenAPI and /docs built inFastAPI's OpenAPI and /docs keep working
CLInest new and nest generatefastapi dev and fastapi run, no code generatoraustial new and austial generate
TestingTest.createTestingModule()TestClient with dependency overridesTest.create_testing_module() with real dependency injection

Dependency injection: Depends() vs the constructor

FastAPI injects dependencies as function parameters, each wired with Depends(). NestJS and Austial inject them into a class constructor, and the container resolves them from the type hints. The second style scales better when many handlers share the same services, because the wiring lives in one module instead of every route.

# FastAPI: dependencies are function parameters
@router.get("/cats/{cat_id}")
async def find_one(cat_id: int, service: CatsService = Depends(get_cats_service)):
    return service.find_one(cat_id)


# Austial: dependencies are constructor parameters, resolved by type hint
@Controller("cats")
class CatsController:
    def __init__(self, service: CatsService):
        self.service = service

    @Get(":id")
    async def find_one(self, id: int):
        return self.service.find_one(id)

Frequently asked questions

Is FastAPI similar to NestJS?

They share some ideas, such as decorators and automatically generated OpenAPI documentation. But FastAPI is a minimal toolkit that leaves the project structure to you, while NestJS prescribes modules, controllers and providers.

Can I use NestJS patterns with FastAPI?

Yes. You can follow the patterns by hand with routers and Depends(), or use a framework such as Austial that adds NestJS-style modules, controllers, providers and guards on top of FastAPI.

Does Austial replace FastAPI?

No. Austial runs on FastAPI. Every route is registered as a real FastAPI APIRouter, so FastAPI's OpenAPI schema and the Swagger UI at /docs keep working.

Last updated

Go deeper in the docs

( Keep reading )

( Click. Copy. Build. )

Seeing “command not found”? Run uv tool update-shell, then open a new terminal. Details