fusonic/ddd-extensions
A lightweight PHP package of Domain-Driven Design building blocks, offering reusable base classes and extensions for entities, value objects, aggregates, and domain events. Helps keep Laravel and plain PHP projects structured around explicit domain models.
Architecture fit. The package is explicitly aimed at Symfony + Doctrine ORM. That is the opposite end of the PHP framework spectrum from a Laravel application, which is Eloquent-first. The DDD primitives it advertises — aggregate roots, entities, value objects, identities, domain events, domain exceptions — are conceptually stack-agnostic, but this library binds them to Doctrine (embeddables, custom DBAL types, likely a postFlush event subscriber) and to Symfony's event dispatcher. Adopting it wholesale in a Laravel codebase implies either running Doctrine inside Laravel or amputating the ORM layer. Neither is a decision a TPM should let a team make by accident.
Integration feasibility. Partial at best. The pure-PHP surface (interfaces, base classes, traits, exceptions) should be usable without the Symfony container, but any Doctrine-coupled code is a hard dependency on doctrine/orm. Laravel already ships symfony/event-dispatcher, so the dispatcher dependency is less of a conflict than it appears; the ORM dependency is the real blocker. Feasibility is therefore conditional on two things: (a) how much of the "building blocks" logic is actually ORM-agnostic, and (b) whether the team is willing to vendor/fork the relevant classes rather than depend on the package at runtime.
Technical risk. High, on several axes. The adoption signals are poor: 1 star, 0 dependents, and an opportunity score of 33.37. That pattern is consistent with an internal library extracted from a single Symfony application, published for convenience, and maintained opportunistically. There is no meaningful community, no ecosystem of consumers, and no evidence of an SLA. Specific risks:
laravel-doctrine/orm if that route is chosen.Key questions. These need answers before any integration commitment:
Doctrine\* or Symfony\*?postFlush, a Symfony subscriber, or PSR-14? Is dispatch transactional?Verdict. Do not adopt as a runtime dependency for a Laravel application. Evaluate it as a reference implementation and a source of small, battle-tested patterns that can be vendored into the domain layer. The DDD primitives are worth ~100–300 lines of in-house code; the package's real value is in showing what those lines look like, not in being installed.
Stack fit. Laravel's event pipeline (events, listeners, queued listeners, DB::afterCommit) is a different model from Symfony's dispatcher and Doctrine's postFlush hook. Domain events recorded on an aggregate and released on flush are a Doctrine-shaped pattern; in Laravel/Eloquent the equivalent idiom is model observers plus DB::afterCommit, or an explicit releaseEvents() call at the transaction boundary of an application service. The package's event mechanics will not port cleanly, and attempting to shoehorn them will produce two competing event systems.
Migration path. Two viable routes, in order of preference:
app/Domain/Support/ or a small internal package, re-namespaced under your own vendor, with attribution. Wire domain-event release to Laravel's dispatcher at your service-layer boundary. This preserves the concepts, removes the external dependency, and keeps the ORM out of the domain.laravel-doctrine/orm, register the package's subscriber and DBAL types, and accept the operational overhead of two persistence paradigms. This is the only route where the package is used as designed, and the only route where the Symfony/Doctrine coupling is an asset rather than a liability. It is almost never the right call for a greenfield Laravel product.Compatibility. Pin and verify: PHP version against your runtime; doctrine/orm major version against any existing Doctrine usage; symfony/event-dispatcher range against Laravel's shipped version (Laravel tracks Symfony closely, but majors can diverge). Run composer why-not against the candidate version set before prototyping. License is MIT, which permits forking and internal redistribution — confirm attribution expectations with legal, but there is no copyleft exposure.
Sequencing.
Recommendation. Route A. Treat the package as documentation, not infrastructure.
Maintenance. Under Route A the ongoing cost is one internal owner and periodic review of a small, stable set of classes — low and predictable. Under Route B the cost is Doctrine operational literacy plus two persistence stacks — materially higher. Under a direct runtime dependency the cost includes tracking upstream releases that may never come; a package with 0 dependents and negligible stars should be assumed to have an undefined maintenance horizon.
Support. There is no commercial support, no SLA, and no meaningful issue history to infer responsiveness. Internal ownership is therefore mandatory regardless of route. Documentation will need to be written, not consumed. Budget for that explicitly.
Scaling. The package itself is thin; runtime overhead is negligible. The scaling risk is architectural: Doctrine's identity map and unit-of-work flush semantics behave differently from Eloquent's immediate saves, and mixing them — or adopting Doctrine's model in a Laravel app — introduces memory growth, flush-ordering surprises, and N+1 patterns that are unfamiliar to most Laravel engineers. Keep the domain layer free of ORM concerns and scaling is a non-issue.
Failure modes to instrument and test.
Ramp-up. The team needs DDD literacy (aggregates, invariants, domain vs. integration events, transaction boundaries) more than package-specific knowledge. Doctrine familiarity is needed only under Route B. A realistic ramp is one sprint for the spike plus convention-setting, with the first production bounded context landing in the following sprint. The package reduces that effort marginally; the architecture decisions and conventions carry the real weight.
Bottom line. Low operational value as a dependency, moderate value as a pattern reference. The 1-star, 0-dependent, low-opportunity profile should be read as "not a platform bet." Recommend a short spike to extract the ideas, an explicit build-not-buy decision, and no runtime coupling to the package.
How can I help you explore Laravel packages today?