One arrow, two schools — and a one-command test that exposes the fakes.
One arrow, two schools
Both diagrams draw the same arrow: source dependencies may only point inward, toward business logic. UI, DB and frameworks live at the rim.
Clean (Martin): four rings — Entities / Use Cases / Interface Adapters / Frameworks & Drivers. Named principle: the Dependency Rule.
Onion (Palermo, DDD-flavored): three layers — Domain Model / Domain Services / Application Services / Infrastructure. Named principle: domain at the center, rich model.
The slide's own footer says it: different names, similar principles. Hexagonal (Ports & Adapters) is the third sibling — the same inward-arrow rule, omitted from the picture.
The real differences (subtler than the picture)
Onion's domain layer is not just data — it is behavior: rich domain objects plus domain services. Clean's Entities can be anemic structs with logic pushed into Use Cases.
Onion traditionally has 3 layers with domain services inside the domain; Clean separates use cases from adapters explicitly.
Both rely on dependency inversion at the boundary: rim code implements interfaces the core declares.
If the core imports flask / sqlalchemy / requests anywhere, the dependency rule is decorative, regardless of folder names.
The checkout test: can you unit-test your checkout logic without booting a web server or a DB? If no, the arrow is fiction.
What the picture hides
"Which to choose" is cargo-cult ("Clean = most popular"). Choice follows team and domain complexity, not popularity.
Neither diagram tells you this: layers without enforced boundaries rot anyway — import cycles, and shared DTOs with ORM annotations leak the DB inward.
The takeaway: the dependency arrow is the actual content. The circle count is branding.
Image-backend outage note (2026-10-11): the primary image model (qwen/qwen-image-3, funded, no 402) garbled core teaching terms on both rolls — including the title word and both column headings — so no PNG was shipped per the quality gate. This is a text-only card carrying the full lesson; a PNG will be back when the backend renders clean again.