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

Laravel Module Loader Laravel Package

sebastiaanluca/laravel-module-loader

Laravel Module Loader lets you split a Laravel application into self-contained modules and automatically registers each module's service providers, routes, configuration, views, translations, and other resources without manual bootstrap code, keeping large projects organized and maintainable.

View on GitHub
Deep Wiki
Context7

Getting Started

Read the deprecation notice first. This package is archived (last release March 2021) and explicitly deprecated. Do not adopt it for new work. If you inherited it, the goal is to understand it well enough to maintain or migrate off it.

Minimal steps for an existing install:

  1. Confirm the installed version and your Laravel version. Releases stop at early 2021, so expect compatibility with roughly Laravel 6–8. Check composer.json constraints before assuming it boots on Laravel 9+.
  2. Open the package source (vendor/sebastiaanluca/laravel-module-loader/src) before trusting the README. The archived README may not match the code, and the exact base class/service provider names matter.
  3. Locate the config (config/modules.php if published, otherwise the package's default config). This is where module paths or module registrations live.
  4. Run php artisan vendor:publish for the package config if it isn't already published, then php artisan config:clear.
  5. Create your first module by making a directory (typically under app/Modules or whatever the config points to), adding a service provider that extends the package's base module provider, and registering it.

First use case: carve one cohesive slice out of a fat app/ — e.g. Billing — and give it its own service provider, routes file, config, views, and migrations. The win is contextual colocation, not framework magic.

Where to look first: the package's service provider (what it registers), the module base provider (what hooks it exposes), and the config file. Those three files tell you 90% of the day-to-day behavior.

Implementation Patterns

One module per bounded context. Treat a module as a vertical slice: Modules/Billing/Providers/BillingServiceProvider.php, Routes/web.php, Config/billing.php, Resources/views, Database/Migrations, Tests. The loader's job is to discover/register these; your job is to keep boundaries honest.

Service provider as the module's entry point. Put bindings, event listeners, and sub-registrations (routes, migrations, views, config merge) in the module provider. This is the standard Laravel pattern; the package just gives you a base class and a registration mechanism.

Register modules centrally, not ad hoc. Keep the list of active modules in the config (or whatever discovery mechanism the package uses) so enabling/disabling a module is a one-line change rather than editing config/app.php in several places. This also makes it trivial to disable a module in a broken state during an incident.

Load routes/config/views/migrations per module. Use the provider's boot methods (loadRoutesFrom, mergeConfigFrom, loadViewsFrom, loadMigrationsFrom) scoped to the module directory. Keep each module's routes file thin — point at controller namespaces inside the module.

Cross-module communication via contracts and events. Modules should not reach into each other's internals. Define an interface in the consuming module (or a small shared Contracts namespace) and bind the implementation in the providing module's provider. Use events for side effects so modules stay decoupled.

Testing pattern. Boot only the module under test where possible; otherwise rely on the full app boot but keep module tests in the module's own Tests directory with its own namespace. This keeps the "delete the module, delete its tests" property intact.

Migration path away. If you're maintaining a legacy install, start mapping each module to a namespace and directory that a modern alternative (e.g. nwidart/laravel-modules) or plain app/ structure would accept. The module boundaries you already have are the valuable artifact; the loader is replaceable.

Gotchas and Tips

It is unmaintained — treat that as the top gotcha. No security patches, no Laravel 9/10/11 compatibility work, and issues/PRs are closed. Pin the version in composer.lock, and budget for replacement. Do not build new features on its extension points unless you're prepared to fork.

Autoloading is the usual failure point. Modules living outside app/ need PSR-4 entries in composer.json (or the package's own autoload handling). After adding a module, run composer dump-autoload — a "class not found" almost always means the namespace/path mapping, not the loader.

Config and route caching. Dynamically registered modules can behave differently under php artisan config:cache and route:cache. If a module works in local but not production, clear both caches first, then check whether module registration runs before the cache is read. This is the single most common "it broke in prod" cause.

Migration paths and rollback. Module migrations loaded via loadMigrationsFrom don't get the app's default database/migrations treatment. Use php artisan migrate --path=Modules/X/Database/Migrations for targeted runs and be explicit about --realpath if the path is relative.

Namespace collisions. Two modules both defining App\Modules\...\User or both publishing config/app.php keys will silently shadow each other. Prefix config keys (billing.stripe_key) and keep class names module-scoped.

Provider ordering and inter-module dependencies. If module A's provider binds something module B resolves at boot, registration order matters. Prefer deferring resolution to register()/boot() boundaries or use $this->app->booted(...) rather than relying on file order.

Enable/disable discipline. Use the central module list to disable a module rather than commenting out code. A half-disabled module (provider removed but routes still cached) causes confusing 404s.

Debugging checklist: (1) composer dump-autoload; (2) php artisan config:clear route:clear; (3) confirm the module is in the registry/config; (4) confirm the provider is actually instantiated (log in register()); (5) check the package's own service provider isn't swallowing exceptions during discovery.

Extension points worth knowing before you fork: the module base provider (override boot/register hooks), the module registry/repository (swap discovery for an explicit list), and the config (paths, namespaces). If you must keep the package alive, these are the seams to patch for newer Laravel versions — but weigh that against migrating to a maintained alternative.

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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings