php-ddd/domain-driven-design
php-ddd/domain-driven-design helps Laravel/PHP developers structure applications around bounded contexts and domain logic, with reusable DDD building blocks and conventions for entities, value objects, aggregates, repositories, services, and domain events.
Architecture fit. This is a tactical DDD building-block library — the familiar vocabulary of entities, value objects, aggregates, domain events, and repository interfaces — packaged as framework-agnostic PHP classes. Architecturally it slots into the domain layer of a hexagonal/onion design and is deliberately ignorant of persistence and delivery mechanisms, which is the correct shape. The critical caveat: DDD is a modelling discipline, not a dependency. A library can supply base classes and naming conventions but cannot enforce aggregate boundaries, ubiquitous language, or context mapping, which is where essentially all of the value and all of the risk in DDD actually lives. Expect the code to be a small surface (likely a few hundred lines across a handful of abstractions); the intellectual content is the pattern documentation, not the implementation.
Integration feasibility. Composer-installable in principle, but this is a 2015-era artifact and should be treated as such. Expect PHP 5.x idioms: no scalar type hints, no return types, no declare(strict_types=1), possibly PSR-0 or mixed autoloading, a pre-PHPUnit-6 test suite, and require-dev pins that will not resolve or will pull vulnerable transitive versions on a modern PHP 8.2/8.3 runtime. Because the upstream repository location is unknown, we cannot review commit history, issue closure patterns, or whether the Packagist name was ever a fork of a more established project — a provenance gap that matters for license hygiene and for judging whether the code is original or a partially-synced mirror.
Technical risk: high, concentrated in three areas.
extends Entity / implements Repository in our domain model. Inheritance-based primitives are invasive and expensive to reverse once hundreds of classes depend on them; a later swap becomes a refactor across every bounded context.Key questions to resolve before committing.
Stack fit. Plain PHP + Composer and PSR-4-friendly, so it composes with Symfony or Laravel service containers without framework lock-in. The friction is not the package, it is the impedance mismatch with our existing data layer. In a Laravel codebase, Eloquent's Active Record model directly contradicts aggregate-rooted persistence; making this package useful implies repository interfaces, hand-rolled or external mapping, and a deliberate separation between app/Domain and Eloquent models. That architectural work is one to two orders of magnitude larger than the package integration itself and must be scoped and approved as its own initiative. The package should never be the reason a bounded context adopts that separation.
Migration path — recommended: extract, do not depend. Treat the repository as a reference implementation. Two viable options:
Entity, ValueObject, AggregateRoot, DomainEvent, Repository) in-house, typed for PHP 8.x, under our own namespace and ownership. Effort is days, not weeks, and it eliminates the archived-dependency problem entirely. Preserve the MIT notice if we lift code verbatim.acme/domain-primitives package we control: modernize syntax, add type declarations, replace the test suite, wire CI and a security policy, document the freeze criteria. Only justified if the upstream code has non-obvious logic we would otherwise reimplement wrong — unlikely at this size.Either way, do not add php-ddd/domain-driven-design as a production dependency at a floating version.
Compatibility checks (1–2 day spike). Inventory the public API and count classes; run PHPStan/PHP_CodeSniffer; install on PHP 8.2/8.3 and run the existing tests; scan for removed functions (each(), create_function, Serializable), deprecated dynamic properties, loose == comparisons inside value-object equality, and namespace collisions; run composer audit and SCA against the resolved tree; confirm the license file and attribution are present and intact.
Sequencing.
Maintenance. Upstream maintenance is zero and will remain zero. Every PHP upgrade, deprecation, and semantic change becomes our problem the moment the code enters the codebase — either through a fork we own or, worse, through copied classes scattered across services. Budget a named owner and a recurring line item, or adopt an explicit "vendored and frozen" policy with a documented review date. Because the package is small and low-profile, it is exactly the kind of dependency that escapes architecture review today and surfaces as unexplained tech debt in eighteen months.
Support. No vendor, no maintainer, no issue tracker we can even locate. Troubleshooting means reading source. Knowledge will concentrate in the one or two engineers who did the spike, giving a bus factor of one. Mitigate with an ADR, a short internal write-up of the abstractions and their intended usage, and a CODEOWNERS entry.
Scaling. The library is in-process code and does not itself present scaling concerns. The scaling questions it invites are architectural and unbounded: aggregate sizing, eventual consistency around domain events, repository query strategy, and read-model projection. The package supplies none of the event bus, serialization, persistence, or transaction boundary machinery — we would build or buy all of it. Evaluate total cost of ownership for the resulting architecture, not the cost of the dependency.
Failure modes to watch.
Ramp-up. Ramp-up on the code is trivial: the API surface is small enough to read in an afternoon. Ramp-up on the practice is not. Team fluency in DDD takes weeks to months and depends on sustained access to domain experts; the package does nothing to accelerate that and, being a 2015 artifact with no current tutorials, examples, or community, adds explanation overhead that a mainstream maintained alternative would not. Plan for DDD training and design-review capacity as the dominant cost, and treat the 29-star archived library as reading material for the spike — not as an onboarding artifact, and not as a production dependency.
How can I help you explore Laravel packages today?