v0.17 is here. Read the release notes →
Open source · Python · Apache-2.0

The Python framework for domain-driven systems.

Your whiteboard, shipped.

Sketch aggregates, events, and bounded contexts. In Protean that model is the architecture, and everything else, the API, the docs, the contracts, is derived from it.

$ pip install protean
Capabilities

Four things almost no framework does.

All four come from one idea: the model is the source of truth, trustworthy enough to build everything else on.

01

Domain compiler

Protean parses your model into a machine-readable Intermediate Representation. Docs, API specs, and contracts are derived from it, so they cannot drift from the code.

02

Always-valid domain

Domain objects are always valid, or they do not exist. Four layers of validation run on every change, and the structure is checked before the first request.

03

Progressive architecture

Start with plain domain-driven design. Add CQRS or event sourcing for one aggregate at a time, in the same codebase, with no rewrite.

04

Infrastructure portability

Your domain knows nothing about databases, brokers, or caches. You swap them in configuration, and the model, the tests, and the rules stay untouched.

See it work

Your model, checked in the browser.

A real Protean domain, running on Pyodide in this page. Press check and Protean reads the design back: what each aggregate enforces, what it is missing, why it matters, and how to fix it. The code is editable, and nothing leaves your browser.

store.py
protean check 2 findings
info AGGREGATE_NO_INVARIANTS
Aggregate Order has no pre/post invariants (own or inherited); it enforces no business rules and may be an anemic data holder.
An aggregate is a consistency boundary. With no pre- or post-invariants it enforces no business rules and is usually an anemic data holder rather than a true aggregate.
Fix Add one or more @invariant.pre or @invariant.post methods expressing the business rules the aggregate must always satisfy, or reconsider whether this concept is an aggregate at all.
warning AGGREGATE_WITHOUT_COMMAND_HANDLER
Aggregate Order has no command handler, no write path exists
An aggregate with no command handler has no write path, nothing can change its state.
Fix Add a command handler for the aggregate, or model it as a read-only projection if no writes are expected.

First check downloads the Python runtime, about 8 MB over the wire, then it is cached by the browser.

Everything derived

Maintain one thing by hand.

Add a field to an Order in most stacks and you touch it in nine places: the model, the migration, the schema, the spec, the client types, the docs, the fixtures, the event, the version.

In Protean you touch the model. Everything else follows from it, so nothing drifts from the drawing.

Progressive architecture

Start as a monolith and grow into services without a rewrite.

Your domain model does not change. Protean moves the seams, from in-process calls to a message broker, through configuration, so the deployment shape becomes a setting you choose.

Your domain model Order · Customer · Shipment: aggregates, invariants, events Written once, never rewritten
plugs into ↓
Stage 01
Monolith
one process, no services
Database
In-memory
Broker
Inline
Stage 02
Scaling
real database + broker
Database
PostgreSQL
Broker
Redis
Cache
Redis
Stage 03
Distributed
async, event-sourced
Database
PostgreSQL
Broker
Redis
Cache
Redis
Event store
Message DB
added or swapped at this stage dimmed = carried over unchanged
The stack grows; only domain.toml changes, never the model.
Ports and adapters

Bring your own infrastructure.

Every external concern sits behind a port. Choose an adapter, or write one, and Protean wires it into your domain.

Database
PostgreSQL
SQLite
Elasticsearch
In-memory
Broker
Redis PubSub
Redis
In-memory
+ custom
Event store
Message DB
In-memory
+ custom
Cache
Redis
In-memory
+ custom
12,000+
tests, about three lines of test per line of code
3.11 → 3.14
every commit runs the core suite across all of them
100k lines
a real system runs on Protean in production today
Apache-2.0
open core, no lock-in, the model is plain Python you own
Whitepaper

Your Domain Model Is the Architecture

One source of truth, an always-valid domain, and why both matter more now that machines write the code.

Read the whitepaper →

Built for backend systems whose hard part is the business rules and the states things move through. It is the wrong fit for raw speed, very high data volume, or table-first apps. Is Protean for you?

Get started

Model your domain. The rest is derived.

About twenty minutes from install to a running, event-driven domain, with no infrastructure decisions to make first.

$ pip install protean
Read the docs →