shahmy / laravel-ddd-toolkit
Laravel Domain-Driven Design toolkit — Artisan commands for enterprise DDD architecture generation
Requires
- php: ^8.1
- illuminate/console: ^9.0|^10.0|^11.0|^12.0|^13.0
- illuminate/contracts: ^9.0|^10.0|^11.0|^12.0|^13.0
- illuminate/filesystem: ^9.0|^10.0|^11.0|^12.0|^13.0
- illuminate/support: ^9.0|^10.0|^11.0|^12.0|^13.0
Requires (Dev)
- laravel/pint: ^1.0
- orchestra/testbench: ^7.0|^8.0|^9.0|^10.0|^11.0
- pestphp/pest: ^2.0|^3.0
This package is auto-updated.
Last update: 2026-06-25 13:09:11 UTC
README
Artisan commands for enterprise Laravel Domain-Driven Design — scaffold complete bounded contexts in seconds.
Overview
laravel-ddd-toolkit is a Composer package that brings a full suite of ddd:* Artisan commands to any Laravel application. It generates the complete DDD layer structure — Application, Domain, Infrastructure, Presentation, and Tests — along with typed PHP 8.3+ class stubs for every common DDD building block.
Works standalone from the command line. Pairs seamlessly with the Laravel DDD Architect VSCode extension.
Requirements
- PHP 8.1+
- Laravel 10, 11, 12, or 13
Installation
composer require shahmy/laravel-ddd-toolkit --dev
The service provider is auto-discovered. Publish the config file:
php artisan vendor:publish --tag=ddd-config
This creates config/ddd.php in your project.
Configuration
config/ddd.php:
return [ // Root directory for all DDD domains (relative to base_path()) 'src_directory' => env('DDD_SRC_DIR', 'src'), // Base PSR-4 namespace mapped to src_directory 'base_namespace' => 'Src', // Name of the cross-domain shared bounded context 'shared_domain' => 'Shared', // Automatically add PSR-4 entry to composer.json after domain creation 'auto_register_namespaces' => true, // Automatically run composer dump-autoload after namespace registration 'auto_dump_autoload' => true, // PHP testing framework for generated test stubs 'test_framework' => env('DDD_TEST_FRAMEWORK', 'pest'), // 'pest' or 'phpunit' // Layer structure created for every new domain 'layers' => [ 'Application' => ['Actions', 'Commands', 'DTOs', 'Events', 'Exceptions', 'Interfaces', 'Jobs', 'Listeners', 'Queries', 'Services', 'UseCases'], 'Domain' => ['Entities', 'Enums', 'Events', 'Exceptions', 'Repositories', 'Services', 'Specifications', 'Traits', 'ValueObjects'], 'Infrastructure' => ['Cache', 'Factories', 'Mappers', 'Providers', 'Services'], 'Infrastructure/Persistence' => ['Eloquent', 'Migrations', 'Repositories', 'Seeders'], 'Presentation/API' => ['Controllers', 'Middleware', 'Requests', 'Resources', 'Routes'], 'Presentation/CLI' => [], 'Presentation/WEB' => [], 'Tests' => ['Feature', 'Unit'], ], ];
Commands
Project initialization
php artisan ddd:init
Creates the src/ directory, scaffolds the Shared bounded context, and registers Src\\ in composer.json.
Domain scaffolding
php artisan ddd:domain Merchant php artisan ddd:domain Merchant --dry-run # preview without creating files php artisan ddd:domain Merchant --force # overwrite if already exists
Generates the full bounded context under src/Merchant/ with all layers and subfolders. Every empty directory receives a .gitkeep. A README.md and module.json are created at the domain root.
Class generators
All class generators follow the same pattern:
php artisan ddd:<type> <Domain> <ClassName> [--force] [--dry-run]
| Command | Output location | Generated class |
|---|---|---|
ddd:entity |
Domain/Entities/ |
Eloquent-backed domain entity |
ddd:repository |
Domain/Repositories/ + Infrastructure/Persistence/Repositories/ |
Interface + Eloquent implementation |
ddd:service |
Domain/Services/ |
Domain service |
ddd:dto |
Application/DTOs/ |
readonly class with fromArray, fromRequest, toArray |
ddd:action |
Application/Actions/ |
Single-responsibility action |
ddd:usecase |
Application/UseCases/ |
Clean Architecture use case |
ddd:event |
Domain/Events/ |
Immutable domain event |
ddd:value-object |
Domain/ValueObjects/ |
readonly value object with invariant validation |
ddd:enum |
Domain/Enums/ |
Backed PHP 8.1+ enum |
ddd:policy |
Domain/ |
Laravel policy |
ddd:resource |
Presentation/API/Resources/ |
API resource |
ddd:request |
Presentation/API/Requests/ |
Form request |
ddd:test |
Tests/Feature/ or Tests/Unit/ |
Pest or PHPUnit test |
Examples:
php artisan ddd:entity Merchant Product php artisan ddd:repository Merchant ProductRepository php artisan ddd:service Merchant PricingService php artisan ddd:dto Merchant CreateProductDTO php artisan ddd:action Merchant CreateProductAction php artisan ddd:usecase Merchant CreateProductUseCase php artisan ddd:event Merchant ProductCreated php artisan ddd:value-object Merchant Money php artisan ddd:enum Merchant ProductStatus php artisan ddd:policy Merchant OrderPolicy php artisan ddd:resource Merchant ProductResource php artisan ddd:request Merchant StoreProductRequest php artisan ddd:test Merchant ProductTest --unit
Generated Domain Structure
src/Merchant/
├── Application/
│ ├── Actions/
│ ├── Commands/
│ ├── DTOs/
│ ├── Events/
│ ├── Exceptions/
│ ├── Interfaces/
│ ├── Jobs/
│ ├── Listeners/
│ ├── Queries/
│ ├── Services/
│ └── UseCases/
├── Domain/
│ ├── Entities/
│ ├── Enums/
│ ├── Events/
│ ├── Exceptions/
│ ├── Repositories/
│ ├── Services/
│ ├── Specifications/
│ ├── Traits/
│ └── ValueObjects/
├── Infrastructure/
│ ├── Cache/
│ ├── Factories/
│ ├── Mappers/
│ ├── Persistence/
│ │ ├── Eloquent/
│ │ ├── Migrations/
│ │ ├── Repositories/
│ │ └── Seeders/
│ ├── Providers/
│ └── Services/
├── Presentation/
│ ├── API/
│ │ ├── Controllers/
│ │ ├── Middleware/
│ │ ├── Requests/
│ │ ├── Resources/
│ │ └── Routes/
│ ├── CLI/
│ └── WEB/
├── Tests/
│ ├── Feature/
│ └── Unit/
├── README.md
└── module.json
Customising Stubs
Publish the built-in stubs to your project:
php artisan vendor:publish --tag=ddd-stubs
Stubs are copied to stubs/ddd/ in your project root. Edit them freely. The toolkit will use your versions automatically — published stubs always take precedence over the package defaults.
Stub placeholders use {{ PLACEHOLDER }} syntax (case-insensitive):
| Placeholder | Value |
|---|---|
{{ NAMESPACE }} |
Full PSR-4 namespace for the class |
{{ CLASS }} |
Class name |
{{ DOMAIN }} |
Domain name |
Package Architecture
src/
├── Commands/ # 15 Artisan commands (DddDomainCommand, DddEntityCommand, …)
├── Generators/
│ ├── DomainGenerator.php # Atomic directory tree scaffolding
│ └── ClassGenerator.php # Stub-based class file generation
├── Support/
│ ├── AtomicFilesystem.php # Transactional filesystem (begin/stage/commit/rollback)
│ ├── ComposerUpdater.php # PSR-4 namespace registration + dump-autoload
│ ├── StubEngine.php # Stub resolution and placeholder replacement
│ └── NamespaceGenerator.php
└── DDDServiceProvider.php
Atomic operations — all file and directory creation runs inside a transaction. Any failure triggers a full rollback, leaving no partial structures on disk.
Testing
composer install
./vendor/bin/pest
./vendor/bin/pest --coverage # requires Xdebug or PCOV
Code style is enforced by Laravel Pint:
./vendor/bin/pint # fix ./vendor/bin/pint --test # check only (CI mode)
VSCode Integration
This package works as a standalone CLI toolkit. If you use VSCode, the Laravel DDD Architect extension detects this package and delegates all generation commands to it — giving you the same results from the Command Palette or sidebar without typing Artisan commands manually.
Contributing
- Fork the repository and branch from
main. - Use Conventional Commits for commit messages.
- Ensure
./vendor/bin/pestpasses and./vendor/bin/pint --testreports no violations. - Add a
CHANGELOG.mdentry under[Unreleased]. - Open a pull request.
Changelog
See CHANGELOG.md for release history.
License
MIT © shahmy