Shared Kernel
debt(d7/e7/b7/t7)
Closest to 'only careful code review or runtime testing' (d7). The detection_hints list deptrac and phpstan as tools, which can detect dependency violations and large shared libraries, but detecting whether the Shared Kernel is growing inappropriately, lacks team governance, or is being misused as a general utility library requires careful code review and architectural awareness. Automated tools can flag structural issues but not the conceptual misuse.
Closest to 'cross-cutting refactor across the codebase' (e7). The quick_fix says to keep the kernel small, but when misuse has already occurred — a Shared Kernel that has grown into a monolithic shared library — remediation requires decomposing the shared model, redistributing concepts to their owning contexts, and coordinating changes across multiple teams and bounded contexts. This is a cross-cutting concern that touches multiple components and teams.
Closest to 'strong gravitational pull' (b7). The applies_to covers web and cli contexts broadly. A Shared Kernel that grows or lacks governance shapes every change made in both bounded contexts — teams must coordinate for every modification, and the kernel exerts gravitational pull on design decisions. Common mistakes confirm the decay pattern: it 'becomes a monolithic shared library' over time, progressively increasing coupling.
Closest to 'serious trap' (t7). The misconception field directly states that developers confuse Shared Kernel with a general shared database or common utility library, which is the opposite of its DDD meaning — a formally governed, minimal, intentionally bounded subset of the domain model. This contradicts how 'shared libraries' work in most other architectural contexts, making it a serious conceptual trap for developers familiar with standard shared library patterns.
Also Known As
TL;DR
Explanation
A Shared Kernel is a deliberate coupling point: two contexts agree to share specific classes (value objects, domain events, DTOs) and coordinate on any changes. It is NOT accidentally shared code — it is a formal agreement. Best for: tightly related contexts owned by the same team, where the coordination cost is lower than maintaining two separate but nearly identical models. Anti-pattern when: teams are independent, the shared portion grows unchecked, or the shared code becomes a dumping ground for anything two contexts need.
Common Misconception
Why It Matters
Common Mistakes
- Shared Kernel that grows over time without governance — becomes a monolithic shared library.
- No team agreement on change process — one team changes the kernel, breaks the other.
- Sharing infrastructure code as a Shared Kernel — infrastructure utilities are not domain concepts.
- Using Shared Kernel to avoid duplicating convenience code — duplication is often better than coupling.
Code Examples
// Shared kernel used as a dumping ground:
namespace SharedKernel;
// Originally: just Money and CustomerId
// 2 years later: 200 classes, utilities, helpers, configs
// Every team change breaks others
// No clear ownership — everyone and nobody owns it
// Disciplined shared kernel — minimal, governed:
namespace SharedKernel;
// Only truly shared domain concepts:
final class Money { /* amount + currency */ }
final class CustomerId { /* UUID value object */ }
final class OrderId { /* UUID value object */ }
// Change process: both teams must review and approve
// Version controlled independently — SharedKernel v2.1
// Both contexts pin to the same version
// Size limit: if > 20 classes, something is wrong