PHPackages                             tey/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. [Utility &amp; Helpers](/categories/utility)
4. /
5. tey/laravel-ddd

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

tey/laravel-ddd
===============

A Laravel toolkit for Domain Driven Design patterns

v3.0.1(2w ago)184243↑550%22MITPHPPHP ^8.3|^8.4CI passing

Since Jan 19Pushed 2w ago3 watchersCompare

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

READMEChangelog (10)Dependencies (17)Versions (35)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

60

—

FairBetter than 98% of packages

Maintenance96

Actively maintained with recent releases

Popularity35

Limited adoption so far

Community21

Small or concentrated contributor base

Maturity75

Established project with proven stability

 Bus Factor1

Top contributor holds 78.7% 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 ~39 days

Recently: every ~14 days

Total

32

Last Release

18d ago

Major Versions

v0.10.0 → v1.0.02024-03-31

v1.2.1 → v2.0.02025-03-02

v2.x-dev → 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 (174 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (26 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/tey-laravel-ddd/health.svg)

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

###  Alternatives

[lunarstorm/laravel-ddd

A Laravel toolkit for Domain Driven Design patterns

18476.4k](/packages/lunarstorm-laravel-ddd)[nativephp/desktop

NativePHP for Desktop

37833.6k8](/packages/nativephp-desktop)[spatie/laravel-pdf

Create PDFs in Laravel apps

1.0k4.3M41](/packages/spatie-laravel-pdf)[nativephp/mobile

NativePHP for Mobile

97255.0k84](/packages/nativephp-mobile)[laravel/ai

The official AI SDK for Laravel.

9782.1M153](/packages/laravel-ai)[friendsoftypo3/content-blocks

TYPO3 CMS Content Blocks - Content Types API | Define reusable components via YAML

101466.4k44](/packages/friendsoftypo3-content-blocks)

PHPackages © 2026

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