geekcell/ddd
A Laravel package that brings Domain-Driven Design building blocks to PHP applications, providing ready-made abstractions for entities, value objects, aggregates, repositories, and domain events so business logic stays clean and framework-independent.
Architecture fit. The package is narrower than its tagline suggests. "Guard rails" implies enforcement — static analysis, architecture tests, CI gates — but the actual artifact described is a set of base classes and contracts: Entity, AggregateRoot (with event recording/release), typed Value Object helpers, repository interfaces, and Laravel auto-discovered service provider bindings. That is scaffolding, not enforcement. A TPM should treat those as two different purchases: scaffolding is cheap to adopt and cheap to abandon; enforcement is what actually reduces architecture drift, and it mostly lives in Pest arch tests, Deptrac, or PHPArkitect rather than in this dependency. Fit is good for a Laravel monolith or modular monolith with two or more bounded contexts and a team that has already committed to DDD. Fit is poor for CRUD-shaped back-office apps, prototypes, and single-squad products with low domain churn, where the inheritance ceremony costs more than it returns. The package does not replace CQRS/ES frameworks (EventSauce, Broadway) — teams already there will find it redundant or conflicting.
Integration feasibility. Technically trivial, organizationally expensive. It is a Composer require with no infrastructure footprint, no migrations, and no operational surface. The real work is retrofit: existing models must be re-expressed against the base classes' contracts, and that is a refactor, not an install. Expect the first one to two sprints to be dominated by decisions (where aggregate boundaries sit, where transactions begin and end, whether domain entities are distinct from Eloquent models) rather than code.
Technical risk. Three material risks, in order:
Key questions. Answer these before any adoption decision:
Stack fit. Natural for a modular monolith where module boundaries are the near-term scaling strategy. Complements Laravel's container, service providers, and event bus for domain event dispatch. Poor fit for a microservice estate where each service is too small to justify aggregates, and poor fit for teams with no engineer who has shipped a DDD codebase — the package supplies the rails but not the judgment.
Migration path. Strangler-fig, context by context, never repository-wide:
Compatibility. Validate against your exact PHP/Laravel minor versions in a throwaway branch, not against the README. Confirm it doesn't suppress or conflict with existing PHPStan/Psalm baselines or Pest arch configuration. Check whether the service provider registration does anything beyond bindings — auto-discovery that mutates container behavior is harder to reason about during upgrades.
Sequencing. Five gates, strictly ordered: (a) license/support/CI diligence, (b) fork-feasibility assessment and a named owner, (c) spike + written pass/fail, (d) convention doc, (e) pilot. Broad rollout should trail the pilot by at least one full release cycle so pain surfaces under real load rather than in a demo. Nothing on the roadmap should depend on this package until gate (c) closes.
Mitigation built into the plan. Write the architecture-test suite (layer rules, no-Eloquent-in-domain, no cross-context imports) as plain Pest/PHPUnit tests in the first week. If the package is later dropped, those tests survive and the enforcement value is retained. This is the cheapest possible hedge and should be non-negotiable.
Maintenance. Near-zero runtime maintenance; non-trivial governance maintenance. It will never page anyone at 3 a.m. But it creates a permanent architectural surface that needs an owner. Assign a named maintainer or small guild responsible for the internal fork, upgrade testing, and adjudicating convention disputes. Budget roughly 2–3 days per quarter for dependency tracking and 1–2 weeks per year for a fork-and-patch event when upstream goes quiet — plan for that event, don't be surprised by it. Mirror the repo internally on day one.
Support. Effectively self-support. Zero dependents means no community knowledge base, no Stack Overflow corpus, no third-party tutorials. Onboarding depends entirely on internal documentation and the reference implementation, which makes those artifacts mandatory deliverables of the spike, not documentation debt. A reasonable posture is to contribute fixes upstream to build a relationship with the maintainer while keeping the internal mirror current.
Scaling. Scales well architecturally — bounded contexts are the correct unit for team scaling and reduce cross-team coupling. Scales poorly on cognitive load if applied everywhere. The scaling risk concentrates at headcount growth: new engineers must learn Laravel idiom, DDD, and this package's specific dialect simultaneously. Mitigate by making the pilot context the onboarding exemplar and by capping adoption at contexts that genuinely have rich invariants.
Failure modes to watch for. Each needs an early-warning signal a TPM can track:
Illuminate imports appearing in domain namespaces. Add a CI rule; this is the highest-probability failure.Ramp-up. Assume 3–5 days of guided onboarding for a mid-level engineer to be productive in an adopted context, plus 1–2 days of reading the package source (which the named maintainer must do first and document). Front-load this: the reference implementation plus a 90-minute walkthrough is worth more than any amount of written convention, and it is the difference between a coherent rollout and each team inventing its own dialect.
Bottom line for the TPM. The package is a cheap accelerator and an expensive commitment. Fund a two-week, one-squad spike with a written pass/fail criterion; write the architecture tests independently regardless of outcome; secure a named fork owner before any second team adopts; and keep it off the roadmap until the pilot survives a full release cycle. If the spike fails, lift the test patterns into your own toolchain — that is still a win, and it is the outcome to plan for by default given zero adoption signal.
How can I help you explore Laravel packages today?