docs: add comparison + 'that-depends or modern-di?' pages by lesnik512 · Pull Request #232 · modern-python/modern-di · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions docs/introduction/comparison.md
53 changes: 53 additions & 0 deletions docs/introduction/that-depends-or-modern-di.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# that-depends or modern-di?

Both [`that-depends`](https://github.com/modern-python/that-depends) and
`modern-di` are dependency-injection frameworks from the same author, in the
[modern-python](https://github.com/modern-python) family. This page helps you
choose.

## Short answer

- **Starting a new project?** Use **modern-di**. It has explicit scopes, no
global state, a small strictly-typed core, and separate framework adapters —
see [Design decisions](design-decisions.md).
- **Already using that-depends?** It remains **actively maintained and
production-proven** — you don't need to migrate. Move when you want explicit
scopes or a no-global-state architecture; the
[migration guide](../migration/from-that-depends.md) maps every concept across.

## How they differ

| | that-depends | modern-di |
|---|---|---|
| Status | actively maintained, production-proven | recommended for new projects |
| Resolution | async + sync (`AsyncFactory`, `await resolve`) | sync only (by design) |
| Container model | the container class is both schema and runtime | `Group` (schema) and `Container` (runtime) are separate |
| Scopes | context-based lifetimes | explicit, enforced scope chain (APP→…→STEP) |
| Global state | resolves directly from the container class | none — you create and pass containers explicitly |
| Integrations | bundled | separate adapter packages (install only what you need) |

## Choose that-depends if…

- You specifically want **async resolution** (`await container.resolve(...)`).
modern-di is sync-only by design and will not add async resolution.
- You want the **simplest possible** setup for a single service and don't need an
explicit scope chain.
- You already run it in production and have no reason to change.

## Choose modern-di if…

- You're starting fresh and want **explicit scopes** and **no global state**.
- You want **one wiring across multiple entrypoints** (FastAPI + FastStream +
Typer + workers) via official adapters.
- You value a **first-party pytest plugin** and a small, strictly-typed core.

## Migrating

The [migration guide](../migration/from-that-depends.md) covers every provider
type and concept, including the conceptual shifts: the schema/runtime split
(`Group` vs `Container`), sync-only resolution, and explicit scopes.

## See also

- [modern-di vs other libraries](comparison.md)
- [Design decisions](design-decisions.md)
2 changes: 2 additions & 0 deletions mkdocs.yml