phpmentors/domain-kata
A Domain-Driven Design library for PHP offering reusable building blocks—entities, value objects, identifiers, repositories, and domain services—to help you model rich, expressive domains with clean, framework-agnostic code.
What this actually is. phpmentors/domain-kata is the PHP Mentors (Japan) "kata" — an exercise/reference artifact demonstrating DDD tactical building blocks in PHP. The v1.4.0 notes confirm the surface is broader than a minimal skeleton: alongside Entity, ValueObject, Identity, DomainEvent, DomainEventPublisher, DomainEventSubscriber, Repository, and Specification, it now ships UsecaseInterface, ServiceInterface (marker), InOutInterface, IdentifiableInterface, and EntityCollectionInterface::toArray(). It remains a teaching vocabulary, not an infrastructure library. That distinction drives every conclusion below, and the new release does not change it.
Architecture fit. Still framework-agnostic, PSR-0/PSR-4-era plain PHP — conceptually compatible with hexagonal/DDD layering inside a Laravel app, mechanically awkward. The release adds three points of friction rather than relieving any:
InOutInterface extends EntityInterface — modelling Input/Output as a domain entity conflates a use-case DTO with an identity-bearing aggregate. Adopting this literally imports a design smell into the domain layer.ServiceInterface is an empty marker: zero compile-time or runtime enforcement, so it documents intent without guaranteeing anything. Laravel has no equivalent and needs none; it would be a naming convention only.EntityCollectionInterface::toArray() pushes a serialization/presentation concern into the domain collection. Convenient for the kata's demos, but a leakage vector we would not carry into a Laravel app where API resources own serialization.DomainEventPublisher still sits awkwardly against Laravel's container-bound dispatcher, and value objects remain hand-rolled rather than custom casts.Integration feasibility. Unchanged and low as a Composer dependency. Critically, the release date is 2015-06-13 — identical to the last-release date already recorded in the assessment. This is not a new maintenance signal; it is confirmation that v1.4.0 is the terminal release. Eleven years without a subsequent tag, PHP 5.x-era constraints, PHPUnit 4 suite: composer require on Laravel 9–11 / PHP 8.2 will fail resolution or fatal on language-level incompatibility. Feasible only as a vendored/forked pattern source — and the added interfaces enlarge the set of things we would deliberately not copy.
Technical risk.
UsecaseInterface/InOutInterface pair invite teams to build ceremonial use-case plumbing (Input/Output objects, service markers) with no behavioural payoff, inflating the domain layer for no measurable gain.Key questions.
InOutInterface and ServiceInterface rather than inherit them by default.Stack fit. Unchanged in substance, with the release sharpening the mapping:
ValueObject → PHP 8.1 readonly classes or Spatie\LaravelData/custom casts; drop the base class.Entity identity/equality, IdentifiableInterface → a small trait or abstract class with getId(); own implementation, no dependency.DomainEvent → Laravel native events + Event::dispatch after transaction commit; drop the static publisher.Repository → interfaces in Domain, Eloquent implementations in Infrastructure.UsecaseInterface / InOutInterface → do not port. Laravel's controller/action + FormRequest + API Resource stack already covers this ground with framework-native validation, authorization, and serialization. Recreating it in the domain layer duplicates the framework.ServiceInterface → do not port; a marker interface with no enforcement is documentation debt.EntityCollection::toArray() → do not port; serialization belongs to resources/transformers.Net: the release nudges the superseded proportion above the previously estimated ~60%. Cherry-pick vocabulary, not code.
Migration path.
reference/domain-kata-v1.4.0, no production dependency.packages/domain (Composer path repository) with declare(strict_types=1), return types, PHPUnit 10 tests, README in English. Explicitly record the deliberate exclusions (InOutInterface, ServiceInterface, toArray(), static publisher) so future contributors don't reintroduce them.Compatibility. Target PHP 8.2+ / Laravel 10–11 / PHPUnit 10. Reject the upstream test suite and any Doctrine examples. Zero runtime dependency on the original package remains the success criterion. There is no upgrade path to plan for, because there will be no further upstream releases.
Sequencing. Unchanged and unaffected by the release: License → in-house base classes + tests → ADR (including exclusions) → single bounded-context pilot (2–4 weeks) → measure (domain-layer coverage, ORM leakage count, and now also ceremony ratio: lines of use-case/DTO scaffolding per unit of behaviour) → widen or stop. Do not sequence this as a platform-wide "DDD initiative" before the pilot proves value; the new interfaces make scope creep marginally more likely, not less.
Maintenance. You inherit 100% of it. The maintained surface is small (single-digit classes), so steady-state cost stays near zero. Budget the initial modernization (est. 3–5 engineer-days including tests) — unchanged, since we are not porting the newly added interfaces. Treat upstream as dead and confirmed final. Pin the fork internally; never reference the public package in composer.json.
Support. No vendor, no SLA, no CVE process. Community support is the PHP Mentors blog/book corpus, primarily Japanese, and the v1.4.0 notes are terse English changelog entries rather than guidance. Plan for translation or an internal champion. Escalation path is "whoever wrote the fork."
Scaling. Code-level patterns do not constrain throughput; the package is not a runtime component. Organizational risks are unchanged — divergent copies of base classes unless distributed as a versioned internal package. The static event publisher, if adopted, risks duplicate dispatch and leaked listeners. The new InOutInterface/ServiceInterface pair adds a mild scaling hazard: each team left to interpret them will invent its own use-case ceremony, producing inconsistent layering across bounded contexts.
Failure modes.
composer require → resolution failure or PHP 8 fatal, misdiagnosed as "package is broken."toArray()-style collection methods.Ramp-up. A senior PHP engineer reads the whole thing in 1–2 days; v1.4.0 adds maybe an hour of reading but a disproportionate amount of decision surface, because each new interface must be explicitly accepted or rejected. Team-level fluency in DDD tactical patterns remains the real cost: 2–4 weeks, best spent with the pilot team rather than as classroom training. Onboarding to the fork is trivial if the ADR and tests exist — and the ADR is now more valuable, since it must record what we chose not to take.
TPM recommendation. Do not adopt as a dependency. v1.4.0 is a 2015 terminal release re-confirming abandonment, not a maintenance signal; it expands the vocabulary but changes none of the risk posture. Use as a reference vocabulary and training artifact, explicitly scope out UsecaseInterface, InOutInterface, ServiceInterface, EntityCollection::toArray(), and the static publisher, fund a small in-house domain-layer package with the license question closed first, and gate broader rollout on the single-context pilot. Value delivered remains pedagogical and architectural, not operational — size the investment accordingly.
How can I help you explore Laravel packages today?