Skip to content

FAQ & Troubleshooting ​

FAQ ​

Do module providers have to extend ModuleServiceProvider? ​

No. A module's providers can be plain Illuminate\Support\ServiceProviders and they will be discovered and registered. You only extend ModuleServiceProvider to get convention loading (config/migrations/views/routes) and attribute wiring (#[Bind], #[Listen]).

Do I have to use the DDD layout? ​

No. make:module has ddd (default), simple, contracts and clean presets, and you can publish the stubs (--tag=modules-stubs) to shape your own structure. See Creating a module.

How can attribute-based config be fast? ​

In development attributes are reflected once per provider and memoised. In production php artisan module:cache compiles discovery, attributes and each module's resolved convention folders into one PHP file, so a request does zero reflection and never touches the filesystem — a module that ships none of the optional folders costs nothing at boot. See Performance.

Can a module declare its own Composer dependencies? ​

Yes — add them to the module's composer.json require. With the recommended path-repository setup, composer update installs them like any package.

Does it work with config:cache and route:cache? ​

Yes. Config is merged at boot, and route loading is skipped when routes are cached, so Laravel's caches behave normally. Run module:cache too for the fastest path.

Can a module register more than one provider? ​

Yes. List them in the module's module.json providers array (or the module composer.json extra.laravel.providers).

Can I use this in a microservice architecture? ​

Yes — as a modular monolith that promotes modules to services, and for shared contract packages between services. See How it works and Private distribution.

Troubleshooting ​

Class "Modules\X\...\XServiceProvider" not found ​

The module's classes aren't autoloaded. Easiest fix: keep modules.autoload enabled (the default) — modules are then autoloaded at runtime with no Composer setup. If you turned it off to autoload via Composer, either:

bash
composer require your-vendor/x-module:@dev   # path repository
composer dump-autoload

or add the module's PSR-4 to the app's root composer.json and composer dump-autoload. See Installation → Autoloading modules.

A new module doesn't show up in module:list ​

  • Run composer require your-vendor/<name>-module:@dev (path-repo) or composer dump-autoload.
  • If you compiled the cache, it's stale — php artisan module:clear.

Changes to a module aren't taking effect (production) ​

The compiled cache is stale. Rebuild or clear it:

bash
php artisan module:clear      # or: php artisan optimize:clear

Don't run module:cache in development — it freezes discovery and attributes.

A module's routes return 404 ​

  • Routes were cached before the module existed — php artisan route:clear.
  • The module has no routes/web.php / routes/api.php, or #[Module(routes: false)] is set.
  • Confirm the module is enabled: php artisan module:list.

Config values are null ​

  • The file must be config/<module>.php (lowercase) or config/config.php; it is merged under the kebab-cased module name (config('my-module.key')).
  • Laravel's config cache is stale — php artisan config:clear.

A disabled module still seems active ​

  • The module name in modules_statuses.json must match the StudlyCase module name exactly.
  • If the module is a Composer-discovered package, its provider self-guards and no-ops when disabled — clear caches (php artisan optimize:clear) if you changed the status while a compiled cache existed.

Views aren't found (View [x::y] not found) ​

The view namespace is the lowercase module name, and resources/views/ must exist. Example: view('billing::invoice') → Modules/Billing/resources/views/invoice.blade.php.

A path-repository symlink: true pointing outside the mounted project directory won't resolve in the container. Either set "options": { "symlink": false } so Composer copies the package into vendor/, or mount the package directory into the container too.

Generated modules get the wrong vendor name ​

Set modules.vendor in config/modules.php (e.g. 'vendor' => 'acme') so make:module names packages acme/<name>-module.