theaddresstechnology/ddd
A Laravel package that brings Domain-Driven Design structure to your application, with practical building blocks for organising domain logic, separating concerns, and keeping business code clean and maintainable. It helps model bounded contexts and keep infrastructure details away from your core dom...
Architecture fit. The core characterization is unchanged: this is a dev-time scaffolding generator, not a runtime library. It emits directories, classes, and boilerplate into the host repository and then gets out of the way, so the architectural question remains whether its opinion about bounded contexts, aggregates, repositories, and service providers matches the one we intend to standardize on. v2.1.0 widens that opinion surface in a way worth flagging: the generator now also takes a position on the testing architecture — Pest-first, tests/ and Tests/ layout discovery, a ddd:setup-tests command that prepares Pest support files and binds feature tests to the application TestCase while keeping unit tests isolated. That is a second convention being frozen alongside the domain layout. For a team that has converged on both a modular monolith structure and Pest, this is consistency at scale; for a team on PHPUnit, or still debating structure, the tool now asks for two decisions in one adoption.
Integration feasibility. Provenance improved substantially. The release notes reference a public repository, a versioned tag (v2.1.0), a docs path, and a CI run with five passing jobs; validation is reported as 83 tests / 496 assertions across PHP 8.4/8.5 × Laravel 12/13, with integration tests executing generated fixtures through the real Pest runner. That is the first real evidence that generated output parses, lints, and instantiates — the evidentiary gap that dominated the prior assessment. Two caveats survive. First, all of it is self-reported; we have not independently reproduced the matrix, and "83 tests" describes the package's own suite, not the fitness of its stubs for our conventions. Second, and more consequential operationally: at publication, Packagist still listed v1.1.14, meaning normal Composer resolution cannot select v2.x until a maintainer refreshes the index. The package is therefore tagged but not installable by the default path — adoption today requires a VCS repositories entry pinned to the tag. The previously flagged future-dated release metadata is partially contextualized (Laravel 13 and PHP 8.5 support implies a forward-looking compatibility matrix) but still warrants direct confirmation against the git tag date rather than the changelog.
Technical risk.
ddd:make Test, with a reflection-based PHPUnit generator retained behind --legacy-phpunit. That escape hatch is good for adopters and a standing drift risk upstream: two code paths, one maintainer, and an incentive to let the legacy path rot.ddd:setup-tests touches test bootstrap and support files. The claim that it preserves existing Pest/TestCase files and application PHPUnit settings is exactly the claim to verify — this is the one command in the package that writes into files we are most likely to have already customized.--no-dev install was validated, which closes the "accidental runtime coupling" concern for the test path specifically but not for generated application classes generally.ddd:make Test (PHPUnit default → Pest default). Handled with a major version and a flag, which is the right call, but existing v1 users must read the changelog to notice.Key questions.
ddd:setup-tests diff cleanly against a repo with an existing Pest.php, custom TestCase, and non-default PHPUnit XML? Can we see the diff it produces on a realistic repo?--legacy-phpunit path have parity in the CI matrix, or is it untested legacy surface?composer.json, and how are they expressed for projects straddling Laravel 12/13?Stack fit. Suitable for Laravel/PHP services that have chosen a domain-oriented layout and Pest. Pest-first test generation makes the package a worse fit than before for PHPUnit-standardized teams, unless they accept --legacy-phpunit as a permanent mode. Still a poor fit for existing services with entrenched structure, for teams without DDD fluency, and for services where composer dependency count is governed by supply-chain policy. Best fit remains a greenfield modular monolith or a new bounded-context module in an existing Laravel app on Laravel 12/13 with Pest 4/5.
Migration path. Still forward-only; do not migrate to it. The prior three modes stand, with one adjustment driven by the release itself:
Note that the test-generation feature is genuinely useful in reference mode: the generated starter cases are explicitly described as todos rather than claimed business coverage, which is an honest framing and makes them a reasonable review checklist artifact even if we never install the package.
Compatibility. Verify before anything else: PHP floor (8.4+ per the CI matrix — likely disqualifying for older services), Laravel 12/13 support, Pest 4/5 constraints, PSR-4 autoload entries including any second root, service provider auto-discovery, and whether generated namespaces match our composer.json mapping rather than a hardcoded App\ prefix. New this release: tests/ vs Tests/ layout handling, --legacy-phpunit availability and parity, and whether application PHPUnit settings and existing Pest bootstrap survive ddd:setup-tests untouched.
Sequencing.
ddd:setup-tests implementation. An hour of reading still substitutes for a week of piloting.--both in a disposable branch, run PHPStan/Larastan and Pint against output, and execute the generated tests to see what fails and how.ddd:setup-tests twice against a repo that already has Pest configured, and diff. Confirm preservation claims and safe-failure behavior on duplicate outputs.Maintenance. In dependency mode the upgrade obligation is now two-dimensional: Laravel major and Pest major, on a single maintainer's schedule. Vendored mode costs more than before — stubs to maintain, an Artisan command, and re-validation on each Laravel/Pest combination — but the cost is knowable. Reference mode remains the lowest carrying cost, now with slightly more to harvest (test scaffolds) and slightly more to document (Pest conventions if we adopt them). In all modes, the tool is not where the burden lives; the architecture and testing conventions it imposes are.
Support. Still no community, no forum surface, no SLA. What improved is debuggability: a public repo, a readable CI configuration, and a docs directory mean an engineer can trace a failure rather than guess. Budget one or two engineers' reading time explicitly. The --legacy-phpunit flag is a support asset for PHPUnit shops and a support liability if we standardize on it — it puts us on the path the maintainer has least incentive to keep current.
Scaling. Runtime scaling is a non-issue; nothing ships to production, and the --no-dev install validation confirms that. Organizational scaling is the axis, and the new test generation strengthens the case: a generator that emits both module structure and matching unit/feature tests is materially better at making twenty engineers produce structurally identical, testable modules than one that only emits classes. The counterweight is unchanged and sharper — if the template encodes a structure or test convention that later proves wrong, the correction is a fleet-wide refactor across both code and tests. And because generated tests are explicitly todos, they scale the shape of coverage without scaling coverage itself; pending tests that pass by virtue of being empty are a familiar way to lose track of what is actually verified.
Failure modes.
ddd:setup-tests producing a subtly different Pest bootstrap than the one already in the repo — duplicate helpers, shadowed TestCase bindings, or PHPUnit settings quietly superseded despite the preservation claim.--legacy-phpunit get second-class output.Ramp-up. Low to evaluate, moderate to institutionalize, and slightly higher than before because testing conventions are now in scope. An engineer runs the generator in under an hour; teaching a team what the generated artifacts mean — domain vocabulary and Pest idioms — is the real cost. Expect two to three days of senior engineer time for the audit, the generation spike, and the setup-tests idempotency check, plus architecture and test review during the first few modules. Net: a low-cost, low-risk experiment with a clear exit ramp that is now backed by real CI evidence; still not a dependency of record until the license, Packagist status, and single-maintainer cadence are resolved.
How can I help you explore Laravel packages today?