Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ddd Bundle Laravel Package

geekcell/ddd-bundle

GeekCell DDD Bundle is a Laravel/PHP package for applying Domain-Driven Design with reusable building blocks and conventions that help organize domain, application, and infrastructure layers into cleaner, more maintainable code.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Premise correction (blocking): geekcell/ddd-bundle is a Symfony bundle, not a Laravel package. The repository name (ddd-symfony-bundle) confirms it. It ships a Bundle subclass, a DI extension, and compiler passes — none of which Laravel boots. There is no composer require path that yields working behavior in a Laravel app; at best the install is inert, at worst it drags symfony/framework-bundle into the dependency graph. Every "leverage" option below is therefore port-and-vendor, not adopt.

Architecture fit: Tactical DDD primitives (aggregate roots, value objects, domain events, repository interfaces, UUIDs) are conceptually framework-agnostic and map cleanly onto Laravel. The packaging is the mismatch. Fit is therefore conditional on how the package is internally split: if src/Domain is free of Symfony imports, we can lift it; if the primitives themselves extend or type-hint Symfony contracts, the extraction cost rises sharply and the value proposition collapses toward "read it as a reference implementation."

Integration feasibility: Low to moderate.

  • Composer resolution: Laravel 11/12 already pulls Symfony 7 components (console, http-foundation, routing, error-handler, var-dumper), so some overlap may resolve — but a framework-bundle or http-kernel requirement is the dealbreaker, since it implies the full kernel.
  • Even on successful install, Laravel's container does not read bundle config trees or run compiler passes. Interface-to-implementation binding for repositories, command handlers, and event subscribers — exactly the value the bundle adds on Symfony — must be rewritten as a ServiceProvider with contextual binding.
  • Attribute/annotation scanning for auto-registration has no Laravel equivalent and must be replaced with explicit registration or a discovery package.

Technical risk: High.

  • Abandonment: repo is archived, 13 stars, 0 dependents, last release 2025-02-25. Upstream is a dead end — no security response, no PHP/Symfony compatibility work. MIT gives legal cover to fork; it gives no engineering cover.
  • Dual-framework runtime: any retained Symfony code in a Laravel process means two container/event idioms and two upgrade cadences in one codebase. This is a persistent cognitive tax, not a one-time integration cost.
  • Signal quality: low adoption plus a package-name/repo-name mismatch suggest a personal or internal-extracted project rather than a maintained library. Treat documentation as untrustworthy until validated against source.
  • Opportunity score 0.53 is consistent with a niche, unmaintained artifact; it does not support a strategic bet.

Key questions for the spike (timebox: 2–3 days):

  1. Does composer.json require symfony/framework-bundle or symfony/http-kernel? (Determines whether install is possible at all.)
  2. What fraction of src/ is Symfony-coupled vs pure PHP domain code? Produce a file-level dependency map.
  3. Which Symfony and PHP version constraints are declared, and do they conflict with our illuminate/* set?
  4. Does it depend on a command/query bus, and if so, is that bus a first-party implementation or a third-party dependency?
  5. Are domain events dispatched synchronously in-process, and is there any after-commit or outbox concept?
  6. Is there a test suite we can run standalone against extracted primitives?
  7. What do we actually want — the patterns, or the wiring? (If patterns, we likely don't need this package at all.)

Recommendation: Do not adopt as a dependency. Evaluate as a pattern reference and a candidate source of vendored primitives, benchmarked against framework-native and cross-framework alternatives before any code is written.

Integration Approach

Stack fit. The bundle's four integration surfaces have direct Laravel counterparts, each requiring a rewrite rather than an adapter:

Bundle mechanism (Symfony) Laravel equivalent we must build
Bundle class + Extension config tree ServiceProvider + config/ddd.php
Compiler passes for tagging/auto-wiring Explicit bindings, ContextualBindingBuilder, or #[Singleton]-style attributes
Symfony EventDispatcher Laravel dispatcher, with DB::afterCommit() for domain events
Bundle console commands Artisan commands
Attribute-based repository resolution Interface binding in the provider; no scanning

Migration path (fork-and-port, gated):

  1. Vendor under our namespace. Fork MIT source into internal/ddd (private VCS or path repository), preserving the license file and attribution. Never depend on the archived upstream.
  2. Sever the framework layer. Delete the bundle class, DI extension, compiler passes, and any symfony/* runtime imports. Target: a src/Domain tree with zero non-stdlib dependencies.
  3. Rebuild the wiring in Laravel. One DomainServiceProvider: bind repository interfaces to Eloquent implementations, register command/query handlers, map domain events to Laravel listeners, and add an afterCommit dispatch decorator.
  4. Bridge persistence deliberately. Domain aggregates must not be Eloquent models. Use a mapper or a repository that hydrates aggregates from query results; do not let Model events double-fire alongside domain events.
  5. Pilot in one bounded context. Pick a module with a real invariant to protect (not a CRUD table). Gate on: aggregate persistence round-trip, event dispatch ordering, and test suite green under our PHP matrix.
  6. Decide build vs. buy-with-alternatives after the pilot, not before.

Compatibility. Three independent version axes must be pinned and re-verified each quarter: our PHP version, our illuminate/* major, and whatever Symfony components remain in the dependency graph (Laravel's own transitive Symfony pins mean a forced major bump can ripple into the framework). If step 1–2 succeed, the Symfony axis disappears entirely — that is the primary argument for porting over adapting.

Sequencing and alternatives. Run the spike as a bake-off, not a single-track evaluation. In parallel, cost out three comparators: (a) hand-rolled primitives (~1 sprint for a small base library), (b) Ecotone, which is deliberately framework-agnostic and supports both Laravel and Symfony, and (c) spatie/laravel-event-sourcing if event sourcing is actually in scope. If (a) lands within roughly the same effort as the port, prefer (a): owning 300 lines of our own primitives beats owning a forked abandoned package. If (b) fits, prefer it: it buys the DDD messaging layer without the fork liability.

Explicit non-goal. Do not attempt to run the Symfony bundle inside Laravel via any shim. The failure mode is a half-booted kernel with silently unbound interfaces — the worst possible outcome, because it breaks at runtime rather than at install.

Operational Impact

Maintenance. We become the sole maintainer of any forked code, permanently. Assign a named owner and add the fork to the same dependency-review cadence as first-party packages. Budget roughly 5–10% of one engineer's time per quarter for PHP/Laravel compatibility upkeep on the extracted primitives — small, but non-zero and permanent. The archived upstream means no rebase path; divergence is one-way.

Support. There is no vendor, no community to escalate to (13 stars, 0 dependents, archived), and likely no responsive issue tracker. All support is internal: a runbook covering the aggregate persistence pattern, the event dispatch lifecycle, and the repository binding convention, plus onboarding docs that explain why the code is forked so no one re-introduces the bundle. Factor documentation into the estimate — it is not optional here.

Scaling. The primitives themselves are negligible overhead; risk lives in the wiring we build around them.

  • Repository implementations are the N+1 hotspot — aggregate hydration often tempts per-entity queries. Mandate query-count assertions in the pilot's test suite.
  • Domain event dispatch multiplies listener work per request. Keep listeners queued by default; synchronous listeners only for in-aggregate invariants.
  • If aggregates are loaded and saved per request, watch memory on batch operations; prefer chunked command handling for bulk jobs.

Failure modes and mitigations:

Failure mode Impact Mitigation
Composer resolves but bundle never boots Silent no-op; interfaces unbound at runtime Never install as a dependency; port only
Interface binding missed in the provider BindingResolutionException in prod, not tests Bind in one provider; add a container-compile smoke test
Double event dispatch (Eloquent model events + domain events) Duplicate side effects, duplicate notifications Disable model events in repositories; single dispatch point via afterCommit
In-process dispatch loses events on transaction rollback or crash Data inconsistency Transactional outbox; afterCommit minimum
Symfony major drift via Laravel's transitive pins Broken install mid-quarter Zero Symfony imports in the extracted code; CI matrix across PHP versions
Fork diverges with no upstream Stale security posture over time Owner + quarterly review; treat as first-party code
Team applies DDD vocabulary without boundaries Anemic or over-engineered domain layer Pilot scoped to one context with a real invariant

Ramp-up. Double learning curve: tactical DDD (aggregates, invariants, bounded contexts, domain events) and Symfony idioms for anyone reading the original source. For a Laravel-only team, expect 2–3 weeks before a mid-level engineer is productive in the ported code, and longer before they can make good boundary decisions — the framework part is teachable; the modeling part is not. Budget one senior engineer as the pattern owner for the first two quarters, and expect the pilot to surface at least one boundary that needs redrawing.

Net TPM read: low strategic value, non-trivial integration cost, permanent (if small) maintenance tail, and a hard architectural mismatch. Sanction the timeboxed spike only to harvest patterns and to make the build-vs-alternatives decision on evidence; do not plan a delivery milestone that depends on this package shipping into a Laravel service.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource