Framework
wemake-services/django-modern-rest avatar
wemake-services/django-modern-rest

django-modern-rest for typed async Django APIs

Modern REST framework for Django with types and async support!

1,514 stars230 forksPythonMIT

At a glance

What is it?
django-modern-rest adds typed schemas, request and response validation, content negotiation, and asynchronous Django support to ordinary Django applications. It fits teams that want modern API declarations without introducing a separate runtime, although its alpha status and Django version ceiling require careful evaluation.
Who is it for?
Adopt django-modern-rest when the application already uses a supported Django version and needs typed asynchronous API endpoints with strict schemas. Do not select it for a production service that requires a stable compatibility promise or for Python below 3.11.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The Django API gap django-modern-rest targets

django-modern-rest is intended for developers who need REST endpoints inside Django applications and want type information to participate in request handling, response construction, and API schema generation. The README describes it as a "Modern REST framework for Django with types and async support," rather than as a replacement web framework. Its documentation says it works with existing Django primitives and packages and does not require a custom runtime. That makes it a layer over a Django deployment rather than a separate application server architecture.

The feature set targets several API-development concerns that would otherwise need separate integration work. According to the README, the framework provides strict validation for requests, responses, and errors. It can generate OpenAPI 3.1 or 3.2 semantic schemas, negotiate response content, and ship default implementations for `json`, `msgpack`, SSE, and Json Lines. It also accepts schemas represented through `pydantic2`, `msgspec`, `attrs`, `dataclasses`, or `TypedDict`, without making one of those libraries mandatory.

The main audience is a Django team that wants explicit API contracts and native asynchronous endpoint definitions. A team already satisfied with Django views, manual serializers, and separate documentation tooling may gain little from adding this framework. The repository metadata classifies version 0.16.0 as `Development Status :: 3 - Alpha`, so adoption decisions should account for the project's pre-1.0 status.

Typed schemas and validation across the request lifecycle

The central mechanism described by the project is schema-driven API handling. An endpoint can express its data contract through one of several supported Python typing approaches. The README names `pydantic2`, `msgspec`, `attrs`, `dataclasses`, and `TypedDict`, while also stating that the framework is not bound to any one of them. This matters because teams can keep an existing model representation instead of translating every type into a framework-owned serializer format.

Validation applies to more than incoming request bodies. The feature list specifically includes strict validation of requests and responses, including errors. That creates a broader contract than a basic request decoder: response construction is also checked against a declared schema, and validation errors become part of the API behavior. The README does not show the exact decorator or class syntax for defining an endpoint, so the precise implementation cannot be inferred from the project description.

The framework also reports an OpenAPI schema out of the box, using OpenAPI 3.1 or 3.2 semantics according to the README. This connects Python-side types with an externally consumable API description, but the README does not explain custom schema mappings, versioning policy, or compatibility checks between generated OpenAPI and Django runtime behavior. Those are concrete checks for a project integrating client generators or maintaining a published API specification.

Asynchronous execution without Django wrapper calls

django-modern-rest states that it supports async Django without requiring `sync_to_async` or `async_to_sync` calls inside its framework layer. It also says the implementation is tested against free-threading builds. Those claims position the project for Python's asynchronous web path while retaining Django as the underlying application framework.

The repository contains a dedicated `dmr` package, a `django_test_app`, extensive `tests`, `typesafety`, and `benchmarks` directories, plus a bundled `dmr_pytest.py` module. This layout shows that testing and type analysis are separate concerns in the project rather than a single test directory. The README also names `mypy`, `pyright`, `ty`, and `pyrefly` as strict type checkers used by the project. However, the repository excerpt does not expose the endpoint execution loop or middleware chain, so it would be inaccurate to claim how request scheduling, database access, or streaming is wired internally.

Async support should still be assessed against the actual application. The README claims compatibility with existing Django packages, but it does not enumerate which third-party Django integrations remain asynchronous end to end. A synchronous ORM operation, authentication backend, or middleware component can impose application-level constraints that the framework's own adapter-free support does not remove.

Repository setup and the limits of the documented tutorial

The README does not provide an application installation command, a minimal endpoint example, or a server start command. It points users to the documentation homepage for getting started, so there is no justified first application example to reproduce from this README. The project metadata confirms that the distribution is named `django-modern-rest`, requires Python 3.11 or later, and depends on `django>=5,<6.2` plus `typing-extensions>=4.12`.

For a source checkout, the repository's `justfile` documents a contributor installation recipe. It synchronizes all dependency groups and extras except the `integration-drivers` group:

bash
just install

That recipe runs `uv sync --all-groups --all-extras --no-group integration-drivers`; it is repository development setup, not a documented consumer installation. A separate recipe includes integration dependencies:

bash
just install-integration

This invokes `uv sync --all-groups --all-extras`. Neither command should be presented as the supported way to add `django-modern-rest` to an unrelated production project, because the README does not say that. The first real API definition must therefore come from the linked documentation rather than from an invented endpoint example.

OpenAPI, content negotiation, and API testing support

The framework treats representation and contract generation as part of API development rather than separate documentation tasks. The README lists default implementations for `json`, `msgpack`, SSE, and Json Lines, along with broader content-negotiation support. This can suit APIs that need more than JSON, but it also increases the combinations that an adopter must test. The README does not define the precedence rules among formats, negotiation failure responses, or configuration for enabling each implementation, so those details remain undocumented.

Testing support is unusually broad in the feature description. Named tools include `schemathesis`, `polyfactory`, `tracecov`, Django's own testing primitives, and a bundled `pytest` plugin. The repository also includes `schemathesis.toml`, and its `justfile` exposes a `test` recipe that combines linting, type checks, examples, package checks, smoke tests, translations, and unit tests. A MySQL-specific recipe starts the database service, installs integration dependencies, and points the suite at `TEST_DATABASE_URL`. The `docker-compose.yaml` exposes MySQL on host port `10000` and PostgreSQL on host port `10001`.

These are useful signs of testing scope, but they are not runtime performance measurements for an adopter's application. The README links to a separate performance page and includes benchmark graphics, while it provides no comparative figures that can be quoted responsibly.

Django REST Framework, plain Django, and upgrade boundaries

A relevant alternative is Django REST Framework. django-modern-rest differentiates itself through strict typing, several schema-model choices, native async support without adapter calls inside the framework, built-in OpenAPI generation, and support for content types beyond ordinary JSON. Django REST Framework is the conventional comparison for an existing Django REST stack, but the README does not document migration steps or a feature-by-feature compatibility matrix. Existing serializers, authentication classes, permissions, and custom framework hooks therefore require separate verification.

Plain Django is the other architectural choice. The README explicitly says django-modern-rest uses existing Django primitives and packages and adds no custom runtime. The trade-off is direct: plain Django keeps the framework surface smaller, while django-modern-rest adds schema validation, generated API descriptions, content negotiation, and API-specific testing facilities. The README does not quantify that added configuration or show how existing Django routes are wrapped.

Maintenance is active according to repository activity. The last push was on 2026-10-16, and releases listed for 2026 include 0.14.0, 0.15.0, and 0.16.0. That frequency does not remove upgrade risk. `pyproject.toml` caps Django below version 6.2 and requires Python `>=3.11`, while the classifiers include Python 3.11 through 3.15 and CPython and PyPy implementations. The MIT license permits reuse under its terms, but an organization should review its own release, notice, and dependency obligations. The `CHANGELOG.md` and migration documentation are the first files to inspect when moving from an earlier release.

Editorial conclusion

Adopt django-modern-rest when the application already uses a supported Django version and needs typed asynchronous API endpoints with strict schemas. Do not select it for a production service that requires a stable compatibility promise or for Python below 3.11. Check the framework's alpha status, the pinned `django>=5,<6.2` range, your chosen schema library, and the documented behavior of every required content format before replacing an existing API layer.

Frequently asked questions

What Python and Django versions does django-modern-rest require?

`pyproject.toml` requires Python 3.11 or later and `django>=5,<6.2`. The project metadata lists Django 5.0 through 6.1 among its supported framework classifiers.

Which schema libraries can django-modern-rest use?

The README lists `pydantic2`, `msgspec`, `attrs`, `dataclasses`, and `TypedDict`. It also states that django-modern-rest is not bound to any one of these libraries.

Does django-modern-rest support asynchronous Django and OpenAPI?

The README states that it supports async Django without `sync_to_async` or `async_to_sync` calls inside the framework. It also states that OpenAPI 3.1 and 3.2 semantic schema generation is included.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. wemake-services/django-modern-rest on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/wemake-services-django-modern-rest.svg)](https://hysenlabs.com/projects/wemake-services-django-modern-rest)

Was this useful?