internachi/modular
A lightweight module system for Laravel apps using Composer path repositories and Laravel package discovery. Create self-contained modules in an app-modules/ directory, following standard Laravel package conventions with minimal extra tooling.
Installation
composer require internachi/modular
Publish Config (Optional but Recommended)
php artisan vendor:publish --tag=modular-config
InterNACHI\) in config/app-modules.php.Create Your First Module
php artisan make:module my-module
app-modules/my-module/ with standard Laravel conventions.composer.json and run:
composer update modules/my-module
Sync Project Configs (Optional)
php artisan modules:sync
phpunit.xml and PhpStorm configs to recognize modules.php artisan make:model User --module=my-module
app-modules/my-module/src/Models/User.php.Directory Structure:
app-modules/
├── my-module/
│ ├── src/ # Core logic (Models, Services, etc.)
│ ├── resources/ # Views, Lang, Assets
│ ├── routes/ # Module-specific routes
│ ├── database/ # Migrations, Seeders, Factories
│ └── tests/ # Module tests
Key Conventions:
Modules\MyModule\ (or your custom namespace) for all module classes.use statements needed for cross-module imports.src/Providers/ (auto-discovered by Laravel).make: CommandsModule-Specific Artisan Commands:
php artisan make:controller AdminController --module=my-module
php artisan make:policy UserPolicy --module=my-module
php artisan make:job ProcessPayment --module=my-module
Database Operations:
php artisan make:migration create_users_table --module=my-module
php artisan db:seed --module=my-module # Runs `Modules\MyModule\Database\Seeders\DatabaseSeeder`
Component Auto-Discovery:
resources/components/ or src/View/Components/ are auto-registered.<x-my-module::component-name />
<x-my-module::nested.component />
Views:
resources/views/ (module-specific paths are auto-resolved).app-modules/my-module/resources/views/dashboard.blade.php → @include('my-module::dashboard').resources/lang/{locale}/.__('my-module::messages.welcome');
routes/web.php (module directory) or routes/api.php.Route::prefix('my-module')->group(function () {
Route::get('/dashboard', [DashboardController::class, 'index']);
});
tests/ are auto-discovered.Modules\Tests\TestCase as the base class for module tests.php artisan test --module=my-module
Register Providers:
src/Providers/ (e.g., MyModuleServiceProvider).Illuminate\Support\ServiceProvider and bind module-specific services.Bootstrapping:
boot() method to register module-specific bindings or listeners:
public function boot()
{
$this->app->bind('my-module.service', function () {
return new MyModuleService();
});
}
Importing Classes:
use statements in Blade or config files):
use Modules\MyModule\Models\User;
Shared Services:
Namespace Conflicts:
Modules\MyModule\) don’t clash with existing app namespaces.App\Modules\) via config/app-modules.php.Composer Path Repository Issues:
composer update modules/my-module fails, manually add the path repository to composer.json:
"repositories": [
{
"type": "path",
"url": "app-modules/*"
}
]
composer dump-autoload after manual changes.Windows Path Normalization:
app-modules/my-module) or configure Composer’s config.platform.check:
composer config platform.check false
PhpStorm IDE Issues:
php artisan modules:sync to update PhpStorm’s library roots.app-modules/* to PhpStorm’s Settings > Languages & Frameworks > PHP > Include Path.Livewire/Laravel Livewire:
--module flag for make:livewire only works if Livewire is installed. Install it first:
composer require livewire/livewire
Migration Conflicts:
Schema::create('my_module_users', function (Blueprint $table) { ... });
Event Listeners:
src/Listeners/ are registered in the module’s provider or use the EventServiceProvider.Check Module Loading:
php artisan modules:list
php artisan modules:clear
Composer Autoload:
composer dump-autoload
Route Debugging:
php artisan route:list
Blade Component Debugging:
resources/views/vendor/composer.json (auto-generated by Laravel).Translation Debugging:
dd(app('translator')->getLoader()->getNamespaces());
Custom Module Stubs:
make:module:
php artisan vendor:publish --tag=modular-stubs
resources/stubs/module/.Dynamic Module Loading:
config/app-modules.php:
'exclude' => [
'disabled-module',
],
Module-Specific Config:
config(['my-module.setting' => 'value']);
config('my-module.setting');
Testing Modules in Isolation:
--env=testing flag and mock dependencies:
php artisan test --env=testing --module=my-module
Extracting Modules to Packages:
vendor/ (e.g., vendor/my-module/).composer.json to require the package.MyModule\).--moduleHow can I help you explore Laravel packages today?