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

Filament Ddd Starter Laravel Package

orebarranco/filament-ddd-starter

A Laravel starter package that pairs Filament admin panel scaffolding with Domain-Driven Design conventions, helping you organize domain, application, and infrastructure layers into maintainable, scalable back-office projects. Useful for bootstrapping DDD-style Filament resources and reducing boiler...

View on GitHub
Deep Wiki
Context7

Getting Started

This is a starter kit, not a library — you consume it once via composer create-project, then you own the code. There is nothing to composer require later, and upstream updates are not pulled in automatically.

composer create-project orebarranco/filament-ddd-starter my-app
cd my-app
cp .env.example .env && php artisan key:generate
php artisan migrate --seed
php artisan make:filament-user   # or use the seeded admin
php artisan serve

First places to look, in this order:

  1. composer.json — confirm the pinned Filament version (v1.0.3 ships Filament 5.10.2) and the PHP/Laravel constraints before you start writing code.
  2. The domain tree (app/Domain, app/Application, app/Infrastructure — exact names vary; run tree -L 3 app to confirm) to see how bounded contexts are separated and where the repository interfaces live.
  3. A single vertical slice end to end: one Filament Resource → its Form/Table schema → the Action it calls → the repository interface → the Eloquent implementation. Read one slice fully before reading anything else; the value of the kit is the convention, not the individual files.
  4. AppServiceProvider / any DomainServiceProvider — this is where interface→implementation bindings are declared and where you will spend most of your wiring time.

First use case: add one trivial CRUD aggregate (e.g. Tag) by copying an existing slice rather than inventing structure. If you can add a domain entity + value object + repository interface + Eloquent repository + Action + Filament Resource without touching framework files outside the provider, the kit is doing its job.

Implementation Patterns

Follow the slice, not the framework. The kit's whole premise is that Laravel's default app/Models + fat controllers is replaced by per-context layers. Practical rules that keep it coherent:

  • Filament Resources are presentation only. They should translate form state into a DTO/command and hand it to an Action. If you find ->save() on an Eloquent model inside a Resource, or business rules in ->rules([...]) beyond shape validation, the boundary is already leaking.
  • Actions are the unit of work. One class, one __invoke() or execute(), one transaction boundary. Call them from Filament Resource pages (CreateRecord, EditRecord, custom Action closures), from queued jobs, and from artisan commands — the same Action should serve all three, which is the actual payoff of the layering.
  • Repositories return domain objects, not builders. Keep Illuminate\Database\Eloquent\Builder out of the domain. If a Filament table needs complex filtering, do it in an Infrastructure query object and expose a read DTO rather than reaching into the domain.
  • Value objects at the edges. Cast primitives to VOs in the Action or a DTO mapper; never let a raw string $email travel through three layers.
  • Domain events over model observers. If the kit wires events, dispatch from the aggregate/Action and let listeners in Infrastructure handle side effects (mail, queues, search indexing). Observers on Eloquent models reintroduce exactly the coupling DDD is meant to remove.

Filament integration tips:

  • Register panel resources by directory if the kit does not already: ->discoverResources(in: app_path('Presentation/Filament/Resources'), for: 'App\\Presentation\\Filament\\Resources') — otherwise new Resources in a non-default namespace silently do not appear.
  • Multi-panel setups (admin vs. tenant) map well onto bounded contexts; give each panel its own discoverResources path and its own auth guard rather than one panel with canAccessPanel() branching everywhere.
  • Use Filament's ->using() on page classes to point at your Action instead of overriding handleRecordCreation() with glue code.

Testing pattern: assert at the Action level with an in-memory or SQLite repository, and keep a thin set of Filament/Livewire tests for the UI. The layering only pays off if the domain tests do not boot the panel.

Gotchas and Tips

Versioning / Packagist history — read this before pinning. v1.0.2 was tagged onto v1.0.1's commit and Packagist never served it correctly; it cannot be fixed retroactively. v1.0.3 is the corrected release. Consequences:

  • Do not pin 1.0.2 in any scaffold script, CI matrix, or internal template — it is unresolvable or resolves to the wrong tree.
  • If you scaffolded between v1.0.1 and v1.0.3 expecting the "v1.0.2" feature set, you have v1.0.1 code. Diff before assuming: https://github.com/orebarranco/filament-ddd-starter/compare/v1.0.1...v1.0.3.
  • Because this is create-project, Composer's version constraint only affects the initial download. Record the starter version in your README; you will not get upgrade prompts.

MFA password confirmation (Filament 5.10.2). Managing app-based multi-factor authentication now requires re-entering the password. Practical fallout:

  • Sessions where auth.password_confirmed_at is stale get bounced to the password-confirmation screen mid-flow. That is intended, not a bug — do not "fix" it by removing the middleware.
  • If you customised the profile/app-authentication page, call the parent implementation or re-apply the confirmation check, otherwise you have silently downgraded security.
  • In tests, actingAs($user) alone is not enough for MFA-management routes. Seed the confirmation window:
    $this->actingAs($user)->withSession(['auth.password_confirmed_at' => time()]);
    
  • Passwordless/social-login-only users have no password to confirm. Decide explicitly whether they may manage MFA (usually: force a password set first) — otherwise they hit a dead end.

DDD-specific pitfalls:

  • Over-layering. Not every CRUD needs a repository, a DTO, an Action, and a domain event. If a slice is pure form-to-table, let it be thin; the kit's conventions are a default, not a mandate.
  • Anemic domain. If every domain class is a property bag and all logic sits in Actions, you have added indirection without gaining anything. Push invariants into entities/VOs where they belong.
  • Missing bindings. A new repository interface that is not bound in the service provider fails at runtime with "Target [Interface] is not instantiable" — usually only on the page that uses it, so it slips past smoke tests.
  • Eloquent leakage. ->toArray(), ->fresh(), ->load() in domain code is the most common regression. Grep for Illuminate\Database outside Infrastructure periodically.
  • Migrations and contexts. If each context owns its tables, keep migration filenames prefixed by context so php artisan migrate ordering stays predictable and rollbacks are scoped.

Debugging:

  • php artisan about plus the Filament version check first — mismatched Filament/Laravel versions after a manual composer update cause the majority of "panel won't render" reports in starter kits.
  • Clear aggressively after structural changes: php artisan filament:clear-cached-components && php artisan optimize:clear.
  • If a Resource 404s, it is almost always namespace discovery or a policy returning false — check canViewAny() before hunting routing.

Extension points worth knowing: panel providers, the AppServiceProvider bindings block, Filament's ->using() on pages, custom Field/Column classes for VO casting, and domain event → listener registration. Those five cover most day-to-day customisation without forking the kit's structure.

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.
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
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console