app/
βββ Http/Controllers/
βββ Models/
βββ Services/
βββ Repositories/
Works well for simple CRUD, but business rules can spread across controllers, services, models, jobs and observers.
Laravel DDD Toolkit helps teams structure large, modular Laravel applications around explicit business domains, clear use cases, ports and adapters.
βΎ Billing/
βΎ Domain/
βΎ Entities/
Invoice.php
βΎ Application/
βΎ UseCases/IssueInvoice/
IssueInvoiceHandler.php
βΎ Ports/Out/
InvoiceRepository.php
βΎ Infrastructure/
βΎ Persistence/Adapters/
EloquentInvoiceRepository.php
βΎ Http/Controllers/
InvoiceController.php
You do not need to abandon Controllers, Eloquent or Artisan. DDD helps you decide where business rules, use cases and infrastructure details should live when the application stops being a simple CRUD.
It is about making the business language visible in the code. Instead of organizing everything only by technical type, you organize important parts of the system around business capabilities.
app/
βββ Http/Controllers/
βββ Models/
βββ Services/
βββ Repositories/
Works well for simple CRUD, but business rules can spread across controllers, services, models, jobs and observers.
app/Modules/Billing/
βββ Domain/
βββ Application/
βββ Infrastructure/
Keeps one business capability together and makes the responsibility of each layer explicit.
A module represents a business capability, such as Billing, Orders, Inventory or Customers.
Think business area, not just a folder.Where entities, value objects and business rules live. This layer should not know about Laravel or Eloquent.
Example: an Invoice decides whether it can be issued.Where use cases coordinate the work: validate intention, call the domain, persist changes and return a result.
Example: IssueInvoiceHandler.Where Laravel-specific details live: controllers, requests, Eloquent models, queues, integrations and adapters.
Laravel stays here, at the edges.The toolkit does not remove Laravel concepts. It gives each one a clearer architectural place.
Controller
Infrastructure/Http
Receives HTTP input and calls a use case.
Service
Application/UseCases
Becomes a specific use case instead of a generic service full of unrelated methods.
Repository interface
Application/Ports/Out
Represents what the application needs from persistence without depending on Eloquent.
Eloquent Model
Infrastructure/Persistence
Handles database details at the infrastructure edge.
Business rule
Domain
Rules that define valid business behavior should stay close to the domain model.
The application has real business rules, multiple modules, long-term maintenance, integrations, or teams that need a shared architectural language.
You are building a tiny CRUD, a prototype, or a screen with no meaningful business behavior. Laravel's default structure may be enough.
This is not a replacement for Laravel's default architecture. Laravel remains excellent for simple CRUD and early-stage products. The toolkit shines when a system needs domain boundaries, stronger cohesion and protection against accidental coupling.
Execution flows inward. Dependencies point inward.
Entities, value objects and business rules
Use cases and inbound/outbound ports
Persistence adapters, Eloquent and integrations
Controllers and HTTP delivery concerns
Useful when controllers grow, generic services multiply, rules spread across the app and business modules start depending on each other.
You still use the service container, Eloquent, events, jobs and testing tools β but from the right architectural edges.
The structure makes discussions concrete: what is the module, the use case, the business rule, the port and the adapter?
Install the toolkit, publish its setup and use the Artisan commands to discover and generate the pieces your application actually needs.
Install the package from Packagist and check the GitHub repository for documentation and examples.
Run the installer to publish configuration and align the initial folders with the selected architecture.
Generate modules and use cases only when the application has real business boundaries to protect.
ddd:install
Publishes configuration and prepares the Laravel project for domain-oriented structure.
Readymake:module {name}
Creates a vertical module with hexagonal structure by default.
Readymake:port {module} {name} --type=out
Creates an outbound application port such as OrderRepository.
Readymake:adapter {module} {name} --port={port} --type=persistence
Creates an infrastructure adapter that implements a port.
Readymake:repository {module} {name}
Generates an infrastructure repository only when enabled in config or forced.
Opt-inControllers coordinate input. The use case executes the intention. The domain protects the rule.
Contributions are especially valuable around documentation, release readiness, dependency hygiene, architectural checks and examples extracted from long-lived applications.