Creating a Module


#The module:make Command

Generate a new module using the module:make artisan command followed by the module name in StudlyCase:

Copied!
php artisan module:make Blog

This creates a Modules/Blog directory with a full scaffolded structure and automatically enables the module.

You can generate multiple modules in a single command:

Copied!
php artisan module:make Blog Shop Users Invoices

#Module Creation Flags

#--plain / -p

Creates a minimal module with no scaffolded files (no controller, no seeder, no service provider boilerplate):

Copied!
php artisan module:make Blog --plain

Useful when you want to build up the module structure from scratch.

#--api

Scaffolds the module for an API — generates an API controller and omits views, Blade layouts, and web routes:

Copied!
php artisan module:make Blog --api

#--web

The default scaffold. Generates web routes, a controller, views, and a Blade layout:

Copied!
php artisan module:make Blog --web

#--disabled / -d

Creates the module but does not enable it. The module will not be booted by Laravel until explicitly enabled:

Copied!
php artisan module:make Blog --disabled

Enable it later with:

Copied!
php artisan module:enable Blog

#--force

Overwrites an existing module with the same name:

Copied!
php artisan module:make Blog --force

#Author flags

Set the author metadata written into the module's composer.json:

Copied!
php artisan module:make Blog --author-name="Jane Smith" --author-email="jane@example.com" --author-vendor="acme"

#Generated Folder Structure

Running php artisan module:make Blog generates the following structure:

Copied!
Modules/
└── Blog/
├── app/
│ ├── Http/
│ │ └── Controllers/
│ │ └── BlogController.php
│ ├── Models/
│ └── Providers/
│ ├── BlogServiceProvider.php
│ └── RouteServiceProvider.php
├── config/
│ └── config.php
├── database/
│ ├── factories/
│ ├── migrations/
│ └── seeders/
│ └── BlogDatabaseSeeder.php
├── resources/
│ ├── assets/
│ │ ├── js/
│ │ │ └── app.js
│ │ └── sass/
│ │ └── app.scss
│ └── views/
│ ├── layouts/
│ │ └── master.blade.php
│ └── index.blade.php
├── routes/
│ ├── api.php
│ └── web.php
├── tests/
│ ├── Feature/
│ └── Unit/
├── composer.json
├── module.json
├── package.json
└── vite.config.js

You can customise which directories are generated by editing the generator section of config/modules.php. Set generate to false for any directory you do not want created:

Copied!
'generator' => [
'controller' => ['path' => 'app/Http/Controllers', 'generate' => true],
'model' => ['path' => 'app/Models', 'generate' => true],
'migration' => ['path' => 'database/migrations', 'generate' => true],
'event' => ['path' => 'app/Events', 'generate' => false],
// ...
],

#module.json

Every module contains a module.json file that defines the module's identity and how it is bootstrapped:

Copied!
{
"name": "Blog",
"alias": "blog",
"description": "",
"keywords": [],
"priority": 0,
"providers": [
"Modules\\Blog\\Providers\\BlogServiceProvider"
],
"files": []
}

name — The display name of the module.

alias — The lowercase identifier used for view namespacing (blog::index), config keys (config('blog.name')), and translation lookups.

priority — Controls the order in which modules are booted and seeded. Lower numbers boot first. Useful when one module depends on another.

providers — Service providers to register when this module is loaded. Add additional providers here if your module has more than one.

files — Additional PHP files to include when the module boots. Useful for helper files or global function definitions:

Copied!
"files": [
"helpers.php"
]

#composer.json

Each module has its own composer.json. This primarily controls the module's PSR-4 autoloading and is required for the wikimedia/composer-merge-plugin to work:

Copied!
{
"name": "nwidart/blog",
"description": "",
"authors": [
{
"name": "Nicolas Widart",
"email": "n.widart@gmail.com"
}
],
"extra": {
"laravel": {
"providers": [],
"aliases": {}
}
},
"autoload": {
"psr-4": {
"Modules\\Blog\\": "app/",
"Modules\\Blog\\Database\\Factories\\": "database/factories/",
"Modules\\Blog\\Database\\Seeders\\": "database/seeders/"
}
}
}

The vendor name in the module's composer.json is set from composer.vendor in config/modules.php. Update this before creating modules if you plan to publish them as packages.

If a module has its own Composer dependencies (e.g. a third-party SDK only used by that module), you can add them to this file. Note that these dependencies are not automatically installed, they must also be added to the root composer.json or required separately.

#Enabling and Disabling Modules

Modules are enabled and disabled via artisan commands. Their state is stored in modules_statuses.json at the project root.

Enable a module:

Copied!
php artisan module:enable Blog

Disable a module:

Copied!
php artisan module:disable Blog

List all modules and their status:

Copied!
php artisan module:list

You can also enable/disable modules programmatically:

Copied!
use Nwidart\Modules\Facades\Module;
 
Module::enable('Blog');
Module::disable('Blog');

#Deleting a Module

Copied!
php artisan module:delete Blog

This permanently removes the Modules/Blog directory. This action cannot be undone.



Laravel Package built by Nicolas Widart.

Maintained by David Carr follow on X @dcblogdev