# Django Ninja: type-hint APIs on top of Django, and where it stops fitting

> Django Ninja builds REST endpoints from Python type hints inside an existing Django project, generating OpenAPI schemas and Swagger UI. It fits teams that want FastAPI-style declarations without leaving Django's ORM, settings and middleware.

**vitalik/django-ninja** — 💨  Fast, Async-ready, Openapi, type hints based framework for building APIs

- Repository: https://github.com/vitalik/django-ninja
- Website: https://django-ninja.dev
- Stars: 9,202 · Forks: 615
- Language: Python
- License: MIT
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/vitalik-django-ninja

## The gap Django Ninja fills between Django views and a typed API layer

Django ships with the ORM, migrations, settings, middleware and an admin. What it does not ship with is a way to declare an HTTP endpoint whose parameters are validated and cast from Python type annotations. Django Ninja adds exactly that layer and nothing else. You keep your project layout, your models, your database configuration and your deployment, and you add a file that declares routes.

The audience is narrow but real. If your codebase is already Django and you want a JSON API that documents itself, the alternative is either writing validation by hand in views or adopting a second framework and losing the ORM integration. Django Ninja sits between those options. The README describes it as a web framework for building APIs with Django and Python 3.6+ type hints, and lists Django-friendly integration with the core and ORM as a feature. It is not a standalone server and it does not replace Django; it is a routing and schema layer that mounts inside a Django URLconf.

## How a NinjaAPI instance turns type hints into routes and an OpenAPI schema

The mechanism is small enough to hold in your head. You instantiate NinjaAPI, decorate functions with @api.get, @api.post and similar, and register the resulting api.urls in urls.py. The function signature is the contract: annotated parameters are read from the query string, the path or the body depending on the operation, validated and cast before your code runs. The return value is serialized to JSON.

Two things fall out of that design. First, the OpenAPI schema is generated from the same annotations, so the documentation cannot drift from the handler unless someone bypasses the annotations. Second, the interactive documentation is served by default at the api/docs path, backed by Swagger UI or Redoc. The README shows both. The schema generation is derived from the operation definitions, not written by hand, which is the main reason to prefer this over manually maintained API documentation.

The pyproject.toml declares Python 3.7 and later, plus Django classifiers from 3.1 through 6.1, and marks the package as Typing :: Typed. That classifier list is the clearest statement of the compatibility surface the maintainers claim.

## Installing django-ninja and getting /api/add to answer

Installation is a single pip command. The README gives no virtualenv or project scaffolding step, which is reasonable: Django Ninja assumes you already have a Django project running.

```bash
pip install django-ninja
```

Next to urls.py, create an api.py file. The README's example defines one GET endpoint whose two parameters are integers.

```python
from ninja import NinjaAPI

api = NinjaAPI()


@api.get("/add")
def add(request, a: int, b: int):
    return {"result": a + b}
```

Then wire it into the URLconf. The README shows the import and the path entry, with the comment marking the line that matters.

```python
...
from .api import api

urlpatterns = [
    path("admin/", admin.site.urls),
    path("api/", api.urls),  # <---------- !
]
```

Start the Django development server and request /api/add with a and b as query parameters. According to the README, the endpoint receives the GET request, validates and type-casts both parameters, returns JSON, and contributes an operation to the generated OpenAPI schema. If you pass a non-integer for a, validation fails before your function body executes.

The interactive docs are at http://127.0.0.1:8000/api/docs, served by Swagger UI or Redoc. That page is generated from the operations you declared, so it appears as soon as the first route exists.

## What Django Ninja does not give you: auth, admin and the DRF comparison

The README does not document an authentication or permission system. It does not mention pagination, throttling, serializers or a browsable API. Those are the areas where Django REST Framework has a long-established answer and Django Ninja leaves the decision to you or to a third-party package. The related search terms people use, django ninja vs drf and django ninja vs django rest framework, point at exactly this gap. If your API needs role-based permissions wired into every endpoint, DRF's class-based views and permission classes are the more complete starting point.

There is also a maintenance and scope question. The project's own README links prominently to a GitHub issue rather than to a feature list, and the documentation site is where the details live. The README itself is thin: installation, one example, a link to the docs, and sponsorship. Anyone evaluating it should read django-ninja.dev rather than the repository front page, because the front page will not tell you how authentication, pagination or versioning are handled.

A second limitation is the dependency on pydantic for validation and serialization. That is the source of the speed claim in the README, and it is also a coupling: your pydantic version, your Django version and your Python version all have to be compatible at once. The pyproject.toml pins requires-python to >=3.7, but the classifiers extend to Python 3.14 and Django 6.1, so the practical matrix is wider than the minimum suggests.

## Django Ninja versus FastAPI: the ORM is the dividing line

FastAPI is the comparison that comes up most, and the difference is not speed. FastAPI is a standalone ASGI framework. It brings its own application object, its own dependency injection system and its own ecosystem of extensions. Django Ninja assumes Django owns the process and mounts inside it.

That single architectural choice decides most evaluations. If your data access is Django models and your background tasks, admin and migrations already live in a Django project, FastAPI means either running two services or reimplementing the ORM layer. If you are starting from nothing and want the widest set of async-native libraries, FastAPI has the larger surface. Django Ninja's async support is documented as a guide in the repository docs, and the README lists async support as one of the reasons for its execution speed, but the framework's centre of gravity remains Django's synchronous request cycle and ORM.

The README also carries a performance benchmark image. Treat it as a claim by the project, not as an independent measurement, and run your own workload against your own models before drawing conclusions.

## Maintenance, releases and what the MIT licence means for you

The repository is not archived, and the last push was on 2026-09-19. The most recent release, v1.7.1, carries the same date, with two alpha releases, v1.7.1a1 and v1.7.1a2, in the weeks before it. That pattern, alphas followed by a stable tag, suggests a release process with a pre-release stage rather than continuous deployment from master.

The licence is MIT, which is permissive and imposes no copyleft obligation on your application. It does require that the copyright notice and permission notice travel with copies or substantial portions of the software. This is a description of the licence text, not legal advice; if your organisation has a licence review process, run it.

Upgrade cost is the harder question. Django Ninja sits between pydantic and Django, so a major pydantic release or a Django version bump can both affect you. The Makefile shows the project's own toolchain: uv for dependency management, ruff for formatting and linting, mypy for type checking, pytest for tests. If you vendor or fork it, that is the toolchain you inherit. For ordinary users, the practical cost is watching pydantic compatibility when you upgrade either side.

## Conclusion

Adopt Django Ninja when you already run Django and want typed endpoints plus a generated OpenAPI schema without a second framework. Skip it if you need a full admin, auth and permissions suite out of the box, or if you are not on Django at all. Before committing, verify the supported Django and Python versions against your deployment, check how your authentication layer attaches to NinjaAPI, and confirm that pydantic is already pinned in your dependency set.

## FAQ

### How is Django Ninja related to Django?

Django Ninja is a layer that runs inside a Django project. You register its api.urls in your Django URLconf, and the README describes it as having good integration with the Django core and ORM.

### What are the disadvantages of Django Ninja?

The README does not document authentication, permissions, pagination or throttling, so those come from you or from third-party packages. It also depends on pydantic for validation and serialization, which adds a version to keep compatible alongside Django and Python.

### What is the Python Ninja package?

The package on PyPI is named django-ninja, and it is a web framework for building APIs with Django and Python type hints. The README's example shows a NinjaAPI instance with a single GET route that validates and type-casts its parameters.

### How to install django ninja?

The README gives one command: pip install django-ninja. After that you create an api.py file next to urls.py and add the api.urls entry to your URL patterns.

### Is Django Ninja async?

The README lists async support as a feature and links to an async support guide in the repository documentation. The project's own documentation at django-ninja.dev is where the details of that support are described.

### Is Django Ninja production ready?

The README states that it is used by multiple companies on live projects, and the pyproject.toml carries the classifier Development Status :: 5 - Production/Stable. The README also invites users to email their feedback for publication.

## Sources

- [License: MIT](https://github.com/vitalik/django-ninja/blob/master/LICENSE)
- [Project website](https://django-ninja.dev)
- [README](https://github.com/vitalik/django-ninja/blob/master/README.md)
- [Releases](https://github.com/vitalik/django-ninja/releases)
- [vitalik/django-ninja on GitHub](https://github.com/vitalik/django-ninja)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/vitalik-django-ninja
