<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Austial</title>
    <description>The latest articles on DEV Community by Austial (@austial).</description>
    <link>https://dev.to/austial</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4241355%2Fd6e971d4-d848-4cf6-b26c-33dc6cc1ce9e.png</url>
      <title>DEV Community: Austial</title>
      <link>https://dev.to/austial</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/austial"/>
    <language>en</language>
    <item>
      <title>A NestJS-like framework for Python: why I built Austial on FastAPI</title>
      <dc:creator>Austial</dc:creator>
      <pubDate>Thu, 12 Nov 2026 16:00:30 +0000</pubDate>
      <link>https://dev.to/austial/a-nestjs-like-framework-for-python-why-i-built-austial-on-fastapi-3k8l</link>
      <guid>https://dev.to/austial/a-nestjs-like-framework-for-python-why-i-built-austial-on-fastapi-3k8l</guid>
      <description>&lt;p&gt;If you are looking for a &lt;strong&gt;NestJS-like framework for Python&lt;/strong&gt;, this is the one I built. NestJS gives a TypeScript backend a clear shape: modules, controllers, providers, guards, pipes and interceptors. When I moved back to Python I missed that shape. FastAPI is excellent, but it deliberately leaves the project structure to you, so every team ends up inventing its own.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://austial.com/nestjs-for-python" rel="noopener noreferrer"&gt;Austial&lt;/a&gt; keeps the NestJS structure and runs on FastAPI and Pydantic. I maintain it, so treat this as a project write-up rather than a neutral review.&lt;/p&gt;

&lt;h2&gt;
  
  
  NestJS for Python: the same ideas
&lt;/h2&gt;

&lt;p&gt;A controller looks the way a NestJS developer expects. Dependencies arrive through the constructor and are resolved from type hints:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Controller&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"cats"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CatsController&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cats_service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;CatsService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cats_service&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cats_service&lt;/span&gt;

    &lt;span class="nd"&gt;@Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;":id"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@UseGuards&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ApiKeyGuard&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;find_one&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cats_service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_one&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The request pipeline is the one you know: guards, pipes, interceptors, the handler, then exception filters.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftkfywyokdix52rod0noq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftkfywyokdix52rod0noq.jpg" alt="The Austial request lifecycle in order: guards, pipes, interceptors, handler, then exception filters." width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is a full table of &lt;a href="https://austial.com/nestjs-for-python#concept-map" rel="noopener noreferrer"&gt;NestJS concepts and their Austial equivalents&lt;/a&gt;: &lt;code&gt;@Module&lt;/code&gt;, &lt;code&gt;@Injectable&lt;/code&gt;, &lt;code&gt;CanActivate&lt;/code&gt;, &lt;code&gt;PipeTransform&lt;/code&gt;, &lt;code&gt;Test.create_testing_module&lt;/code&gt; and the CLI.&lt;/p&gt;

&lt;h2&gt;
  
  
  NestJS vs FastAPI: what stays FastAPI
&lt;/h2&gt;

&lt;p&gt;Every route is registered as a real FastAPI &lt;code&gt;APIRouter&lt;/code&gt;. Pydantic validates input, and &lt;code&gt;/docs&lt;/code&gt; and &lt;code&gt;/openapi.json&lt;/code&gt; keep working. Austial adds structure; it does not replace the server.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbvh55i2qyonuv8p4r0tg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbvh55i2qyonuv8p4r0tg.jpg" alt="NestJS structure with FastAPI underneath: Austial adds modules, controllers, providers, guards, pipes and interceptors on top of FastAPI." width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are weighing the options, I wrote a side-by-side &lt;a href="https://austial.com/nestjs-vs-fastapi" rel="noopener noreferrer"&gt;NestJS vs FastAPI comparison&lt;/a&gt; covering language, structure, dependency injection, validation and testing, and a shorter note on &lt;a href="https://austial.com/austial-vs-fastapi" rel="noopener noreferrer"&gt;when plain FastAPI is enough&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dependency injection in Python, by constructor
&lt;/h2&gt;

&lt;p&gt;FastAPI injects dependencies as function parameters with &lt;code&gt;Depends()&lt;/code&gt;. NestJS and Austial inject them into a class constructor and let a container resolve them from 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. More on &lt;a href="https://austial.com/python-dependency-injection" rel="noopener noreferrer"&gt;constructor-based dependency injection in Python&lt;/a&gt;, including scopes and custom providers.&lt;/p&gt;

&lt;h2&gt;
  
  
  A FastAPI project structure that scales
&lt;/h2&gt;

&lt;p&gt;A new project gets one folder per concern: the root module and feature modules under &lt;code&gt;src/app/&lt;/code&gt;, shared guards and services under &lt;code&gt;src/shared/&lt;/code&gt;, and non-Python assets such as email templates under &lt;code&gt;src/templates/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fscz1ird5xigbh8d1jqdl.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fscz1ird5xigbh8d1jqdl.jpg" alt="An Austial project tree: src with main.py, an app folder holding app_module.py and modules, a shared folder with guards, services and pipes, and a templates folder for email." width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The reasoning behind it is in &lt;a href="https://austial.com/fastapi-project-structure" rel="noopener noreferrer"&gt;a FastAPI project structure that scales&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Migrating from NestJS to Python
&lt;/h2&gt;

&lt;p&gt;Because the structure carries over, a port is mostly translating syntax and libraries rather than redesigning. I put the order that works, a task-by-task mapping and a worked controller into a guide on &lt;a href="https://austial.com/nestjs-to-python-migration" rel="noopener noreferrer"&gt;migrating from NestJS to Python&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does not carry over
&lt;/h2&gt;

&lt;p&gt;Austial is not a 1:1 port of NestJS. There is no RxJS (interceptors are plain async code), FastAPI is the only HTTP platform, the built-in ORM supports PostgreSQL and SQLite, and GraphQL is code-first through Strawberry. Module visibility is opt-in with &lt;code&gt;strict_modules=True&lt;/code&gt;. The &lt;a href="https://docs.austial.com" rel="noopener noreferrer"&gt;docs&lt;/a&gt; list the gaps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv tool install austial
austial new my-app
&lt;span class="nb"&gt;cd&lt;/span&gt; my-app &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; uv sync &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; uv run austial serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://docs.austial.com/first-steps" rel="noopener noreferrer"&gt;First Steps&lt;/a&gt; page walks through the scaffold. The package is on &lt;a href="https://pypi.org/project/austial/" rel="noopener noreferrer"&gt;PyPI&lt;/a&gt; and the source is on &lt;a href="https://github.com/austial/austial-py" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;, MIT licensed, Python 3.11+.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is there a NestJS-like framework for Python?&lt;/strong&gt;&lt;br&gt;
Yes. Austial is a NestJS-style web framework for Python, built on FastAPI, with modules, controllers, providers, constructor-based dependency injection, guards, pipes, interceptors, a CLI and a testing module.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the NestJS equivalent in Python?&lt;/strong&gt;&lt;br&gt;
There is no official NestJS port. Austial is the closest match: it keeps NestJS's module, controller and provider structure and request pipeline, and runs on FastAPI instead of Express or Fastify.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does Austial replace FastAPI?&lt;/strong&gt;&lt;br&gt;
No. It runs on FastAPI, so FastAPI's OpenAPI schema and the Swagger UI at &lt;code&gt;/docs&lt;/code&gt; keep working.&lt;/p&gt;

&lt;p&gt;It is new and in beta. I would love feedback on the module system and on what is missing for your use case.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>fastapi</category>
      <category>nestjs</category>
    </item>
  </channel>
</rss>
