pijler / laravel-modules
Simple package for organizing Laravel projects using modules.
Installs: 1
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/pijler/laravel-modules
Requires
- php: ^8.2
- laravel/framework: ^11.0|^12.0
Requires (Dev)
- inertiajs/inertia-laravel: ^2.0
- laravel/pint: ^1.25
- orchestra/testbench: ^10.6
- pestphp/pest: ^4.1
- pestphp/pest-plugin-laravel: ^4.0
README
This package provides a simple yet powerful structure for organizing Laravel applications into independent modules, allowing for a cleaner, more scalable, and maintainable architecture.
Each module is a mini Laravel application with its own routes, views, lang, configs, console, events, policies, and observers, all automatically managed by the ModuleServiceProvider
.
📦 Installation
Add the package to your Laravel project:
composer require pijler/laravel-modules
Make sure your composer.json
autoload includes the Modules\
namespace:
"autoload": { "psr-4": { "Modules\\": "modules/" } }
Then run:
composer dump-autoload
🧩 Module Structure
Each module should follow the structure below inside the modules/
directory:
modules/
└── Blog/
├── app/
│ ├── Console/
│ │ └── Kernel.php
│ ├── Http/
│ │ ├── Controllers/
│ │ └── Middleware/
│ └── Providers/
│ ├── AppServiceProvider.php
│ └── RouteServiceProvider.php
├── config/
│ ├── config.php
│ └── another.php
├── lang/
│ ├── en-US.json
│ └── pt_BR.json
├── resources/
│ └── views/
│ └── index.blade.php
└── routes/
└── web.php
⚙️ Module Registration
Each module must contain an AppServiceProvider
that extends the base ModuleServiceProvider
class.
Example:
<?php namespace Blog\Providers; use Modules\ModuleServiceProvider; class AppServiceProvider extends ModuleServiceProvider { /** * The module slug. */ protected string $slug = 'blog'; /** * The module name. */ protected string $module = 'Blog'; /** * Boot the gates for the module. */ protected function bootGates(): void { // } /** * Boot the events for the module. */ protected function bootEvents(): void { // } /** * Boot the policies for the module. */ protected function bootPolicies(): void { // } /** * Boot the observers for the module. */ protected function bootObservers(): void { // } }
Then, register the provider in bootstrap/providers.php
:
return [ /* * Modules Service Providers... */ Blog\Providers\AppServiceProvider::class, ];
Add a namespace mapping for the module in your composer.json
:
"autoload": { "psr-4": { "Blog\\": "modules/Blog/app/" } }
🧠 Internal Functionality
The base ModuleServiceProvider
automatically handles the booting of all module resources.
✅ Views
Automatically loads views from:
resources/views
And makes them available under the module namespace ($slug
):
@include('blog::index')
✅ Translations
Supports both JSON and PHP translation files.
Automatically loads from:
lang/
Usage examples:
trans('Hello world'); // JSON trans('blog::messages.welcome'); // PHP
✅ Configuration
Automatically loads and merges:
- A single
config.php
file - Or multiple files inside the
config/
directory
They can be accessed via config("{$slug}.key")
.
✅ Commands & Schedule
If a app/Console/Kernel.php
exists within the module, the provider:
- Registers Artisan commands located in the /Commands directory.
- Registers scheduled tasks defined in the
schedule(Schedule $schedule)
method.
Example:
namespace Blog\Console; use Illuminate\Console\Scheduling\Schedule; use Modules\BaseKernel; class Kernel extends BaseKernel { /** * Define the application's command schedule. */ public function schedule(Schedule $schedule): void { $schedule->command('blog:clean-posts')->daily(); } /** * Register the commands for the application. */ public function commands(): array { return $this->load(__DIR__.'/Commands'); } }
✅ Dynamic Booting
The provider automatically attempts to execute the following methods, if they exist:
bootGates()
bootEvents()
bootPolicies()
bootObservers()
This allows additional resources to be registered without overriding boot()
.
🔍 Helpers
module_has(string $module): bool
Checks if a module exists inside the modules/
directory.
Parameters
Name | Type | Description |
---|---|---|
$module |
string |
The name of the module to check. |
Return
Type | Description |
---|---|
bool |
true if the module exists, false otherwise. |
Example
if (module_has('Users')) { // The "Users" module exists }
module_path(string $module, string $path = ''): string
Returns the full path to a module directory inside modules/
.
Parameters
Name | Type | Description |
---|---|---|
$module |
string |
The name of the module. |
$path |
string |
Additional path within the module (optional). |
Return
Type | Description |
---|---|
string |
The absolute path to the module directory. |
Example
$path = module_path('Users'); // Returns something like: /var/www/app/modules/Users $configPath = module_path('Users', 'config/module.php'); // Returns: /var/www/app/modules/Users/config/module.php
🧩 Benefits
✅ Modular and independent organization
✅ Automatic loading of configs, views, and translations
✅ Native integration with Scheduler and Artisan
✅ Dynamic boot for gates, policies, observers, and events
✅ Fully compatible with the Laravel ecosystem
📝 License
Open-source under the MIT license.