PHPackages                             lunarstorm/laravel-ddd - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. lunarstorm/laravel-ddd

Abandoned → [tey/laravel-ddd](/?search=tey%2Flaravel-ddd)Library[Framework](/categories/framework)

lunarstorm/laravel-ddd
======================

A Laravel toolkit for Domain Driven Design patterns

v3.0.1(1mo ago)18488.4k↓24.9%24MITPHPPHP ^8.3|^8.4CI passing

Since Jan 19Pushed 1w ago3 watchersCompare

[ Source](https://github.com/jaspertey/laravel-ddd)[ Packagist](https://packagist.org/packages/lunarstorm/laravel-ddd)[ Docs](https://github.com/jaspertey/laravel-ddd)[ RSS](/packages/lunarstorm-laravel-ddd/feed)WikiDiscussions main Synced 3d ago

READMEChangelog (10)Dependencies (66)Versions (38)Used By (0)

Domain Driven Design Toolkit for Laravel
========================================

[](#domain-driven-design-toolkit-for-laravel)

[![Latest Version on Packagist](https://camo.githubusercontent.com/d0faccdf54ee5fa801e25f653eacbac03ff5c7b2e44fa395e9811e8ce5ee79a3/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7465792f6c61726176656c2d6464642e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/tey/laravel-ddd)[![GitHub Tests Action Status](https://camo.githubusercontent.com/553e1a64142c9111d1de9e70d0746cdbec26de1f9f4639cdb3183cd74e90c194/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6a61737065727465792f6c61726176656c2d6464642f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/jaspertey/laravel-ddd/actions?query=workflow%3Arun-tests+branch%3Amain)[![GitHub Code Style Action Status](https://camo.githubusercontent.com/e26f322f5064af9b8cc1eb4f57a21858fcd8596160b9134cb4a732d0d122563f/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6a61737065727465792f6c61726176656c2d6464642f6669782d7068702d636f64652d7374796c652d6973737565732e796d6c3f6272616e63683d6d61696e266c6162656c3d636f64652532307374796c65267374796c653d666c61742d737175617265)](https://github.com/jaspertey/laravel-ddd/actions?query=workflow%3A%22Fix+PHP+code+style+issues%22+branch%3Amain)[![Total Downloads](https://camo.githubusercontent.com/246b0f3e67a5377774010e5cc09fbb907cc4a21cf5b927e700b0b31960292b66/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7465792f6c61726176656c2d6464642e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/tey/laravel-ddd)

Laravel-DDD is a toolkit to support domain driven design (DDD) in Laravel applications. One of the pain points when adopting DDD is the inability to use Laravel's native `make` commands to generate objects outside the `App\*` namespace. This package aims to fill the gaps by providing equivalent commands such as `ddd:model`, `ddd:dto`, `ddd:view-model` and many more.

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require tey/laravel-ddd
```

Important

**Upgrading from `lunarstorm/laravel-ddd` v2?** First update to v2.1.2, then run `ddd:upgrade`:

```
composer require lunarstorm/laravel-ddd:"^2.1.2"
php artisan ddd:upgrade
```

See [UPGRADING](UPGRADING.md) for full details.

You may initialize the package using the `ddd:install` artisan command. This will publish the [config file](#config-file), register the domain path in your project's composer.json psr-4 autoload configuration on your behalf, and allow you to publish generator stubs for customization if needed.

```
php artisan ddd:install
```

### Configuration

[](#configuration)

For first-time installations, a config wizard is available to populate the `ddd.php` config file interactively:

```
php artisan ddd:config wizard
```

For existing installations with a config file published from a previous version, you may use the `ddd:config update` command to rebuild and merge it with the latest package copy:

```
php artisan ddd:config update
```

See [Configuration Utility](#config-utility) for details about other available options.

### Peer Dependencies

[](#peer-dependencies)

The following additional packages are suggested (but not required) while working with this package.

- Data Transfer Objects: [spatie/laravel-data](https://github.com/spatie/laravel-data)
- Actions: [lorisleiva/laravel-actions](https://github.com/lorisleiva/laravel-actions)

The default DTO and Action stubs of this package reference classes from these packages. If this doesn't apply to your application, you may [publish and customize the stubs](#customizing-stubs) accordingly.

### Deployment

[](#deployment)

In production, ensure you run `php artisan ddd:optimize` during the deployment process to [optimize autoloading](#autoloading-in-production). If you already run `php artisan optimize` in production, this will be handled automatically.

### Version Compatibility

[](#version-compatibility)

LaravelLaravelDDD9.x - 10.24.x0.x**[0.x README](https://github.com/jaspertey/laravel-ddd/blob/v0.10.0/README.md)**10.25.x1.x11.x1.x11.44.x2.x12.x2.x11.x - 13.x3.xSee **[UPGRADING](UPGRADING.md)** for more details about upgrading across different versions.

Usage
-----

[](#usage)

### Syntax

[](#syntax)

All domain generator commands use the following syntax:

```
# Specifying the domain as an option
php artisan ddd:{object} {name} --domain={domain}

# Specifying the domain as part of the name (short-hand syntax)
php artisan ddd:{object} {domain}:{name}

# Not specifying the domain at all, which will then
# prompt for it (with auto-completion)
php artisan ddd:{object} {name}
```

Available Commands
------------------

[](#available-commands)

### Generators

[](#generators)

The following generators are currently available:

CommandDescriptionUsage`ddd:model`Generate a domain model`php artisan ddd:model Invoicing:Invoice`

 Options:
 `--migration|-m`
 `--factory|-f`
 `--seed|-s`
 `--controller --resource --requests|-crR`
 `--policy`
 `-mfsc`
 `--all|-a`
 `--pivot|-p`
`ddd:factory`Generate a domain factory`php artisan ddd:factory Invoicing:InvoiceFactory``ddd:dto`Generate a data transfer object`php artisan ddd:dto Invoicing:LineItemPayload``ddd:value`Generate a value object`php artisan ddd:value Shared:DollarAmount``ddd:view-model`Generate a view model`php artisan ddd:view-model Invoicing:ShowInvoiceViewModel``ddd:action`Generate an action`php artisan ddd:action Invoicing:SendInvoiceToCustomer``ddd:cast`Generate a cast`php artisan ddd:cast Invoicing:MoneyCast``ddd:channel`Generate a channel`php artisan ddd:channel Invoicing:InvoiceChannel``ddd:command`Generate a command`php artisan ddd:command Invoicing:InvoiceDeliver``ddd:controller`Generate a controller`php artisan ddd:controller Invoicing:InvoiceController`

 Options: inherits options from *make:controller*`ddd:event`Generate an event`php artisan ddd:event Invoicing:PaymentWasReceived``ddd:exception`Generate an exception`php artisan ddd:exception Invoicing:InvoiceNotFoundException``ddd:job`Generate a job`php artisan ddd:job Invoicing:GenerateInvoicePdf``ddd:listener`Generate a listener`php artisan ddd:listener Invoicing:HandlePaymentReceived``ddd:mail`Generate a mail`php artisan ddd:mail Invoicing:OverduePaymentReminderEmail``ddd:middleware`Generate a middleware`php artisan ddd:middleware Invoicing:VerifiedCustomerMiddleware``ddd:migration`Generate a migration`php artisan ddd:migration Invoicing:CreateInvoicesTable``ddd:notification`Generate a notification`php artisan ddd:notification Invoicing:YourPaymentWasReceived``ddd:observer`Generate an observer`php artisan ddd:observer Invoicing:InvoiceObserver``ddd:policy`Generate a policy`php artisan ddd:policy Invoicing:InvoicePolicy``ddd:provider`Generate a provider`php artisan ddd:provider Invoicing:InvoiceServiceProvider``ddd:resource`Generate a resource`php artisan ddd:resource Invoicing:InvoiceResource``ddd:rule`Generate a rule`php artisan ddd:rule Invoicing:ValidPaymentMethod``ddd:request`Generate a form request`php artisan ddd:request Invoicing:StoreInvoiceRequest``ddd:scope`Generate a scope`php artisan ddd:scope Invoicing:ArchivedInvoicesScope``ddd:seeder`Generate a seeder`php artisan ddd:seeder Invoicing:InvoiceSeeder``ddd:class`Generate a class`php artisan ddd:class Invoicing:Support/InvoiceBuilder``ddd:enum`Generate an enum`php artisan ddd:enum Customer:CustomerType``ddd:interface`Generate an interface`php artisan ddd:interface Customer:Contracts/Invoiceable``ddd:trait`Generate a trait`php artisan ddd:trait Customer:Concerns/HasInvoices`Generated objects will be placed in the appropriate domain namespace as specified by `ddd.namespaces.*` in the [config file](#config-file).

### Config Utility (Since 1.2)

[](#config-utility-since-12)

A configuration utility was introduced in 1.2 to help manage the package's configuration over time.

```
php artisan ddd:config
```

Output:

```
 ┌ Laravel-DDD Config Utility ──────────────────────────────────┐
 │ › ● Run the configuration wizard                             │
 │   ○ Rebuild and merge ddd.php with latest package copy       │
 │   ○ Detect domain namespace from composer.json               │
 │   ○ Sync composer.json from ddd.php                          │
 │   ○ Exit                                                     │
 └──────────────────────────────────────────────────────────────┘

```

These config tasks are also invokeable directly using arguments:

```
# Run the configuration wizard
php artisan ddd:config wizard

# Rebuild and merge ddd.php with latest package copy
php artisan ddd:config update

# Detect domain namespace from composer.json
php artisan ddd:config detect

# Sync composer.json from ddd.php
php artisan ddd:config composer
```

### Other Commands

[](#other-commands)

```
# Show a summary of current domains in the domain folder
php artisan ddd:list

# Cache domain manifests (used for autoloading)
php artisan ddd:optimize

# Clear the domain cache
php artisan ddd:clear
```

Advanced Usage
--------------

[](#advanced-usage)

### Application Layer (since 1.2)

[](#application-layer-since-12)

Some objects interact with the domain layer, but are not part of the domain layer themselves. By default, these include: `controller`, `request`, `middleware`. You may customize the path, namespace, and which `ddd:*` objects belong in the application layer.

```
// In config/ddd.php
'application_path' => 'app/Modules',
'application_namespace' => 'App\Modules',
'application_objects' => [
    'controller',
    'request',
    'middleware',
],
```

The configuration above will result in the following:

```
ddd:model Invoicing:Invoice --controller --resource --requests
```

Output:

```
├─ app
|   └─ Modules
│       └─ Invoicing
│           ├─ Controllers
│           │   └─ InvoiceController.php
│           └─ Requests
│               ├─ StoreInvoiceRequest.php
│               └─ UpdateInvoiceRequest.php
├─ src/Domain
    └─ Invoicing
        └─ Models
            └─ Invoice.php

```

### Custom Layers (since 1.2)

[](#custom-layers-since-12)

Often times, additional top-level namespaces are needed to hold shared components, helpers, and things that are not domain-specific. A common example is the `Infrastructure` layer. You may configure these additional layers in the `ddd.layers` array.

```
// In config/ddd.php
'layers' => [
    'Infrastructure' => 'src/Infrastructure',
],
```

The configuration above will result in the following:

```
ddd:model Invoicing:Invoice
ddd:trait Infrastructure:Concerns/HasExpiryDate
```

Output:

```
├─ src/Domain
|   └─ Invoicing
|       └─ Models
|           └─ Invoice.php
├─ src/Infrastructure
    └─ Concerns
        └─ HasExpiryDate.php

```

After defining new layers in `ddd.php`, make sure the corresponding namespaces are also registered in your `composer.json` file. You may use the `ddd:config` helper command to handle this for you.

```
# Sync composer.json with ddd.php
php artisan ddd:config composer
```

### Nested Objects

[](#nested-objects)

For any `ddd:*` generator command, nested objects can be specified with forward slashes.

```
php artisan ddd:model Invoicing:Payment/Transaction
# -> Domain\Invoicing\Models\Payment\Transaction

php artisan ddd:action Invoicing:Payment/ProcessTransaction
# -> Domain\Invoicing\Actions\Payment\ProcessTransaction

php artisan ddd:exception Invoicing:Payment/PaymentFailedException
# -> Domain\Invoicing\Exceptions\Payment\PaymentFailedException
```

This is essential for objects without a fixed namespace such as `class`, `interface`, `trait`, each of which have a blank namespace by default. In other words, these objects originate from the root of the domain.

```
php artisan ddd:class Invoicing:Support/InvoiceBuilder
# -> Domain\Invoicing\Support\InvoiceBuilder

php artisan ddd:interface Invoicing:Contracts/PayableByCreditCard
# -> Domain\Invoicing\Contracts\PayableByCreditCard

php artisan ddd:interface Invoicing:Models/Concerns/HasLineItems
# -> Domain\Invoicing\Models\Concerns\HasLineItems
```

### Subdomains (nested domains)

[](#subdomains-nested-domains)

Subdomains can be specified with dot notation wherever a domain option is accepted.

```
# Domain/Reporting/Internal/ViewModels/MonthlyInvoicesReportViewModel
php artisan ddd:view-model Reporting.Internal:MonthlyInvoicesReportViewModel

# Domain/Reporting/Customer/ViewModels/MonthlyInvoicesReportViewModel
php artisan ddd:view-model Reporting.Customer:MonthlyInvoicesReportViewModel

# (supported by all commands where a domain option is accepted)
```

### Overriding Configured Namespaces at Runtime

[](#overriding-configured-namespaces-at-runtime)

If for some reason you need to generate a domain object under a namespace different to what is configured in `ddd.namespaces.*`, you may do so using an absolute name starting with `/`. This will generate the object from the root of the domain.

```
# The usual: generate a provider in the configured provider namespace
php artisan ddd:provider Invoicing:InvoiceServiceProvider
# -> Domain\Invoicing\Providers\InvoiceServiceProvider

# Override the configured namespace at runtime
php artisan ddd:provider Invoicing:/InvoiceServiceProvider
# -> Domain\Invoicing\InvoiceServiceProvider

# Generate an event inside the Models namespace (hypothetical)
php artisan ddd:event Invoicing:/Models/EventDoesNotBelongHere
# -> Domain\Invoicing\Models\EventDoesNotBelongHere

# Deep nesting is supported
php artisan ddd:exception Invoicing:/Models/Exceptions/InvoiceNotFoundException
# -> Domain\Invoicing\Models\Exceptions\InvoiceNotFoundException
```

### Custom Object Resolution

[](#custom-object-resolution)

If you require advanced customization of generated object naming conventions, you may register a custom resolver using `DDD::resolveObjectSchemaUsing()` in your AppServiceProvider's boot method:

```
use Tey\LaravelDDD\Facades\DDD;
use Tey\LaravelDDD\ValueObjects\CommandContext;
use Tey\LaravelDDD\ValueObjects\ObjectSchema;

DDD::resolveObjectSchemaUsing(function (string $domainName, string $nameInput, string $type, CommandContext $command): ?ObjectSchema {
    if ($type === 'controller' && $command->option('api')) {
        return new ObjectSchema(
            name: $name = str($nameInput)->replaceEnd('Controller', '')->finish('ApiController')->toString(),
            namespace: "App\\Api\\Controllers\\{$domainName}",
            fullyQualifiedName: "App\\Api\\Controllers\\{$domainName}\\{$name}",
            path: "src/App/Api/Controllers/{$domainName}/{$name}.php",
        );
    }

    // Return null to fall back to the default
    return null;
});
```

The example above will result in the following:

```
php artisan ddd:controller Invoicing:PaymentController --api
# Controller [src/App/Api/Controllers/Invoicing/PaymentApiController.php] created successfully.
```

Customizing Stubs
-----------------

[](#customizing-stubs)

This package ships with a few ddd-specific stubs, while the rest are pulled from the framework. For a quick reference of available stubs and their source, you may use the `ddd:stub --list` command:

```
php artisan ddd:stub --list
```

### Stub Priority

[](#stub-priority)

When generating objects using `ddd:*`, stubs are prioritized as follows:

- Try `stubs/ddd/*.stub` (customized for `ddd:*` only)
- Try `stubs/*.stub` (shared by both `make:*` and `ddd:*`)
- Fallback to the package or framework default

### Publishing Stubs

[](#publishing-stubs)

To publish stubs interactively, you may use the `ddd:stub` command:

```
php artisan ddd:stub
```

```
 ┌ What do you want to do? ─────────────────────────────────────┐
 │ › ● Choose stubs to publish                                  │
 │   ○ Publish all stubs                                        │
 └──────────────────────────────────────────────────────────────┘

 ┌ Which stub should be published? ─────────────────────────────┐
 │ policy                                                       │
 ├──────────────────────────────────────────────────────────────┤
 │ › ◼ policy.plain.stub                                        │
 │   ◻ policy.stub                                              │
 └────────────────────────────────────────────────── 1 selected ┘
  Use the space bar to select options.

```

You may also use shortcuts to skip the interactive steps:

```
# Publish all stubs
php artisan ddd:stub --all

# Publish one or more stubs specified as arguments (see ddd:stub --list)
php artisan ddd:stub model
php artisan ddd:stub model dto action
php artisan ddd:stub controller controller.plain controller.api

# Options:

# Publish and overwrite only the files that have already been published
php artisan ddd:stub ... --existing

# Overwrite any existing files
php artisan ddd:stub ... --force
```

To publish multiple stubs with common prefixes at once, use `*` or `.` as a wildcard ending to indicate "stubs that starts with":

```
php artisan ddd:stub listener.
```

Output:

```
Publishing /stubs/ddd/listener.typed.queued.stub
Publishing /stubs/ddd/listener.queued.stub
Publishing /stubs/ddd/listener.typed.stub
Publishing /stubs/ddd/listener.stub
```

Domain Autoloading and Discovery
--------------------------------

[](#domain-autoloading-and-discovery)

Autoloading behaviour can be configured with the `ddd.autoload` configuration option. By default, domain providers, commands, policies, and factories are auto-discovered and registered.

```
'autoload' => [
    'providers' => true,
    'commands' => true,
    'policies' => true,
    'factories' => true,
    'migrations' => true,
    'listeners' => false,
],
```

### Service Providers

[](#service-providers)

When `ddd.autoload.providers` is enabled, any class within the domain layer extending `Illuminate\Support\ServiceProvider` will be auto-registered as a service provider.

### Console Commands

[](#console-commands)

When `ddd.autoload.commands` is enabled, any class within the domain layer extending `Illuminate\Console\Command` will be auto-registered as a command when running in console.

### Policies

[](#policies)

When `ddd.autoload.policies` is enabled, the package will register a custom policy discovery callback to resolve policy names for domain models, and fallback to Laravel's default for all other cases. If your application implements its own policy discovery using `Gate::guessPolicyNamesUsing()`, you should set `ddd.autoload.policies` to `false` to ensure it is not overridden.

### Factories

[](#factories)

When `ddd.autoload.factories` is enabled, the package will register a custom factory discovery callback to resolve factory names for domain models, and fallback to Laravel's default for all other cases. Note that this does not affect domain models using the `Tey\LaravelDDD\Factories\HasDomainFactory` trait. Where this is useful is with regular models in the domain layer that use the standard `Illuminate\Database\Eloquent\Factories\HasFactory` trait.

If your application implements its own factory discovery using `Factory::guessFactoryNamesUsing()`, you should set `ddd.autoload.factories` to `false` to ensure it is not overridden.

### Migrations

[](#migrations)

When `ddd.autoload.migrations` is enabled, paths within the domain layer matching the configured `ddd.namespaces.migration` namespace will be auto-registered as a database migration path and recognized by `php artisan migrate`.

### Event Listeners (Since 2.1.1)

[](#event-listeners-since-211)

When `ddd.autoload.listeners` is enabled, the package will automatically discover and register event listeners and event subscribers found within the domain layer, using Laravel's native event discovery mechanism (i.e., `#[ListensTo]` attribute or `$listen` property on the listener).

This is opt-in and disabled by default:

```
'autoload' => [
    // ...
    'listeners' => false, // set to true to enable
],
```

When enabled, any listener class within the domain layer that handles a specific event — via the `handle()` method or the `#[ListensTo]` attribute — will be automatically registered with Laravel's event dispatcher. Classes that implement a `subscribe()` method (event subscribers) are also detected and registered via `Event::subscribe()`.

### Ignoring Paths During PSR-4 Class Scanning

[](#ignoring-paths-during-psr-4-class-scanning)

To specify folders that should be excluded from PSR-4 class scanning, add them to the `ddd.autoload_ignore` configuration option. By default, the `Tests` and `Database/Migrations` folders are excluded.

```
'autoload_ignore' => [
    'Tests',
    'Database/Migrations',
],
```

Note

This setting only affects PSR-4 class scanning (i.e., auto-discovery of Service Providers, Console Commands, Policies, Factories, and Listeners). It has no effect on migration path discovery, which uses a separate mechanism driven by `ddd.autoload.migrations`.

Paths specified here are relative to the root of each domain. e.g., `src/Domain/Invoicing/{path-to-ignore}`. If more advanced filtering is needed, a callback can be registered using `DDD::filterAutoloadPathsUsing(callback $filter)` in your AppServiceProvider's boot method:

```
use Tey\LaravelDDD\Facades\DDD;
use Symfony\Component\Finder\SplFileInfo;

DDD::filterAutoloadPathsUsing(function (SplFileInfo $file) {
    if (basename($file->getRelativePathname()) === 'functions.php') {
        return false;
    }
});
```

The filter callback is based on Symfony's [Finder Component](https://symfony.com/doc/current/components/finder.html#custom-filtering).

### Disabling Autoloading

[](#disabling-autoloading)

You may disable autoloading by setting the respective autoload options to `false` in the configuration file as needed, or by commenting out the autoload configuration entirely.

```
// 'autoload' => [
//     'providers' => true,
//     'commands' => true,
//     'policies' => true,
//     'factories' => true,
//     'migrations' => true,
//     'listeners' => false,
// ],
```

Autoloading in Production
-------------------------

[](#autoloading-in-production)

In production, you should cache the autoload manifests using the `ddd:optimize` command as part of your application's deployment process. This will speed up the auto-discovery and registration of domain providers and commands. The `ddd:clear` command may be used to clear the cache if needed. If you are already running `php artisan optimize`, `ddd:optimize` will be included within that pipeline. The framework's `optimize` and `optimize:clear` commands will automatically invoke `ddd:optimize` and `ddd:clear` respectively.

Configuration File
------------------

[](#configuration-file)

This is the content of the published config file (`ddd.php`):

```
return [

    /*
    |--------------------------------------------------------------------------
    | Domain Layer
    |--------------------------------------------------------------------------
    |
    | The path and namespace of the domain layer.
    |
    */
    'domain_path' => 'src/Domain',
    'domain_namespace' => 'Domain',

    /*
    |--------------------------------------------------------------------------
    | Application Layer
    |--------------------------------------------------------------------------
    |
    | The path and namespace of the application layer, and the objects
    | that should be recognized as part of the application layer.
    |
    */
    'application_path' => 'app/Modules',
    'application_namespace' => 'App\Modules',
    'application_objects' => [
        'controller',
        'request',
        'middleware',
    ],

    /*
    |--------------------------------------------------------------------------
    | Custom Layers
    |--------------------------------------------------------------------------
    |
    | Additional top-level namespaces and paths that should be recognized as
    | layers when generating ddd:* objects.
    |
    | e.g., 'Infrastructure' => 'src/Infrastructure',
    |
    */
    'layers' => [
        'Infrastructure' => 'src/Infrastructure',
        // 'Integrations' => 'src/Integrations',
        // 'Support' => 'src/Support',
    ],

    /*
    |--------------------------------------------------------------------------
    | Object Namespaces
    |--------------------------------------------------------------------------
    |
    | This value contains the default namespaces of ddd:* generated
    | objects relative to the layer of which the object belongs to.
    |
    */
    'namespaces' => [
        'model' => 'Models',
        'data_transfer_object' => 'Data',
        'view_model' => 'ViewModels',
        'value_object' => 'ValueObjects',
        'action' => 'Actions',
        'cast' => 'Casts',
        'class' => '',
        'channel' => 'Channels',
        'command' => 'Commands',
        'controller' => 'Controllers',
        'enum' => 'Enums',
        'event' => 'Events',
        'exception' => 'Exceptions',
        'factory' => 'Database\Factories',
        'interface' => '',
        'job' => 'Jobs',
        'listener' => 'Listeners',
        'mail' => 'Mail',
        'middleware' => 'Middleware',
        'migration' => 'Database\Migrations',
        'notification' => 'Notifications',
        'observer' => 'Observers',
        'policy' => 'Policies',
        'provider' => 'Providers',
        'resource' => 'Resources',
        'request' => 'Requests',
        'rule' => 'Rules',
        'scope' => 'Scopes',
        'seeder' => 'Database\Seeders',
        'trait' => '',
    ],

    /*
    |--------------------------------------------------------------------------
    | Base Model
    |--------------------------------------------------------------------------
    |
    | The base model class which generated domain models should extend. If
    | set to null, the generated models will extend Laravel's default.
    |
    */
    'base_model' => null,

    /*
    |--------------------------------------------------------------------------
    | Base DTO
    |--------------------------------------------------------------------------
    |
    | The base class which generated data transfer objects should extend. By
    | default, generated DTOs will extend `Spatie\LaravelData\Data` from
    | Spatie's Laravel-data package, a highly recommended data object
    | package to work with.
    |
    */
    'base_dto' => 'Spatie\LaravelData\Data',

    /*
    |--------------------------------------------------------------------------
    | Base ViewModel
    |--------------------------------------------------------------------------
    |
    | The base class which generated view models should extend. By default,
    | generated domain models will extend `Domain\Shared\ViewModels\BaseViewModel`,
    | which will be created if it doesn't already exist.
    |
    */
    'base_view_model' => 'Domain\Shared\ViewModels\ViewModel',

    /*
    |--------------------------------------------------------------------------
    | Base Action
    |--------------------------------------------------------------------------
    |
    | The base class which generated action objects should extend. By default,
    | generated actions are based on the `lorisleiva/laravel-actions` package
    | and do not extend anything.
    |
    */
    'base_action' => null,

    /*
    |--------------------------------------------------------------------------
    | Autoloading
    |--------------------------------------------------------------------------
    |
    | Configure whether domain providers, commands, policies, factories,
    | migrations, and event listeners should be auto-discovered and registered.
    |
    */
    'autoload' => [
        'providers' => true,
        'commands' => true,
        'policies' => true,
        'factories' => true,
        'migrations' => true,
        'listeners' => false,
    ],

    /*
    |--------------------------------------------------------------------------
    | PSR-4 Autoload Ignore Folders
    |--------------------------------------------------------------------------
    |
    | Folders that should be excluded from PSR-4 class scanning
    | (auto-discovery of providers, commands, policies, factories,
    | and listeners), relative to the root of each domain.
    |
    | This does not affect migration path discovery, which is controlled
    | separately by the autoload.migrations option above.
    |
    | e.g., src/Domain/Invoicing/
    |
    | If more advanced filtering is needed, a callback can be registered
    | using `DDD::filterAutoloadPathsUsing(callback $filter)` in
    | the AppServiceProvider's boot method.
    |
    */
    'autoload_ignore' => [
        'Tests',
        'Database/Migrations',
    ],

    /*
    |--------------------------------------------------------------------------
    | Caching
    |--------------------------------------------------------------------------
    |
    | The folder where the domain cache files will be stored. Used for domain
    | autoloading.
    |
    */
    'cache_directory' => 'bootstrap/cache/ddd',
];
```

Testing
-------

[](#testing)

```
composer test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [Jasper Tey](https://github.com/JasperTey)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

65

—

FairBetter than 99% of packages

Maintenance95

Actively maintained with recent releases

Popularity51

Moderate usage in the ecosystem

Community21

Small or concentrated contributor base

Maturity75

Established project with proven stability

 Bus Factor1

Top contributor holds 78.5% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~38 days

Recently: every ~0 days

Total

33

Last Release

43d ago

Major Versions

v0.10.0 → v1.0.02024-03-31

v1.2.1 → v2.0.02025-03-02

v2.1.1 → v3.x-dev2026-05-20

v2.1.2 → v3.0.02026-05-21

PHP version history (5 changes)v0.1.0PHP ^8.1

v0.2.0PHP ^8.1|^8.2

v0.9.0PHP ^8.1|^8.2|^8.3

v2.0.0PHP ^8.2|^8.3|^8.4

v2.1.0PHP ^8.3|^8.4

### Community

Maintainers

![](https://www.gravatar.com/avatar/96d210bee695fe717349834aba99885545cbc144e66b9c4d78691db6fd62461c?d=identicon)[JasperTey](/maintainers/JasperTey)

---

Top Contributors

[![jaspertey](https://avatars.githubusercontent.com/u/1280844?v=4)](https://github.com/jaspertey "jaspertey (175 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (27 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (15 commits)")[![panyamin](https://avatars.githubusercontent.com/u/391653?v=4)](https://github.com/panyamin "panyamin (1 commits)")[![PhilippeThouvenot](https://avatars.githubusercontent.com/u/21236874?v=4)](https://github.com/PhilippeThouvenot "PhilippeThouvenot (1 commits)")[![atom1285](https://avatars.githubusercontent.com/u/83918488?v=4)](https://github.com/atom1285 "atom1285 (1 commits)")[![zain534102](https://avatars.githubusercontent.com/u/69460904?v=4)](https://github.com/zain534102 "zain534102 (1 commits)")[![danny-de-wit](https://avatars.githubusercontent.com/u/1607633?v=4)](https://github.com/danny-de-wit "danny-de-wit (1 commits)")[![meditto](https://avatars.githubusercontent.com/u/26086016?v=4)](https://github.com/meditto "meditto (1 commits)")

---

Tags

artisanddddomain-driven-designlaravellaravelDomain Driven Designdddlaravel-dddtey

###  Code Quality

TestsPest

Static AnalysisPHPStan

### Embed Badge

![Health badge](/badges/lunarstorm-laravel-ddd/health.svg)

```
[![Health](https://phpackages.com/badges/lunarstorm-laravel-ddd/health.svg)](https://phpackages.com/packages/lunarstorm-laravel-ddd)
```

###  Alternatives

[laravel/framework

The Laravel Framework.

34.8k543.8M20.1k](/packages/laravel-framework)[laravel/ai

The official AI SDK for Laravel.

1.0k3.2M195](/packages/laravel-ai)[laravel/boost

Laravel Boost accelerates AI-assisted development by providing the essential context and structure that AI needs to generate high-quality, Laravel-specific code.

3.5k21.5M596](/packages/laravel-boost)[wnx/laravel-backup-restore

A package to restore database backups made with spatie/laravel-backup.

213421.0k2](/packages/wnx-laravel-backup-restore)[spatie/laravel-pdf

Create PDFs in Laravel apps

1.0k4.8M47](/packages/spatie-laravel-pdf)[nativephp/desktop

NativePHP for Desktop

39742.4k8](/packages/nativephp-desktop)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
