edalzell / laravel-features
Self-contained feature modules for Laravel with auto-registration of routes, migrations, views, events, and seeders
Requires
- php: ^8.3
- composer/composer: ^2.8
- edalzell/laravel-features-plugin: ^0.1
- illuminate/contracts: ^12.0 || ^13.0
Requires (Dev)
- brain/monkey: ^2.7
- larastan/larastan: ^3.0
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.8
- orchestra/testbench: ^10.0 || ^11.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-arch: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
- phpstan/extension-installer: ^1.4
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- spatie/laravel-ray: ^1.40
README
Add self-contained features to your Laravel app or package, including all resources/routes/etc.
.
└── app/
...
└── features/
│ └── MyGreatFeature/
│ ├── config/
│ │ └── my-great-feature.php
│ ├── database/
│ │ ├── factories
│ │ ├── migrations
│ │ └── seeders
│ ├── resources
│ ├── routes
│ └── src/
│ ├── Models
│ ├── ...
│ └── ServiceProvider.php
Each feature behaves like a mini Laravel app. The following are auto-registered and booted:
| Phase | What |
|---|---|
| Register | Config, Migrations, Routes, Seeders, Views |
| Boot | Config publishing, Listeners, Policies, Seeders |
Installation
You can install the package via composer:
composer require edalzell/laravel-features
Usage
To add a new feature in your app:
php artisan make:feature MyGreatFeature
To add feature to a package:
php artisan make:feature MyGreatFeature the-dev/my-package
This creates a ServiceProvider that extends FeatureServiceProvider — everything is auto-registered with no further code required.
Option 1: Extend FeatureServiceProvider
The zero-friction path. Your provider gets boot() and register() for free:
class MyGreatFeatureServiceProvider extends FeatureServiceProvider { // nothing needed — everything is auto-registered }
Override any of these protected methods to customise behaviour:
protected function configFileName(): string // default: kebab-cased feature name protected function configGroup(): string // default: '' (no subdirectory) protected function configPublishHandle(): string // default: kebab-cased feature name protected function featuresPath(): string // default: base_path('features/FeatureName')
Option 2: Standalone Features object
When your provider already extends another class, wire up Features directly:
use Edalzell\Features\Features; class MyServiceProvider extends SomeOtherProvider { private Features $features; public function __construct(Application $app) { parent::__construct($app); $this->features = (new Features($this)) ->path($this->featuresPath()) ->name($this->name()) ->configFileName($this->configFileName()) ->configGroup($this->configGroup()) ->configPublishHandle($this->configPublishHandle()); } public function boot(): void { $this->features->bootFeature(); } public function register(): void { $this->features->registerFeature(); } }
Features derives the path, namespace, and app from your provider via reflection. You only need to call the fluent setters when overriding the defaults.
Auto-discovering features
Use the HasFeatures trait in any service provider to automatically register all features from a directory. In your app, add it to AppServiceProvider:
use Edalzell\Features\Concerns\HasFeatures; class AppServiceProvider extends ServiceProvider { use HasFeatures; public function register(): void { $this->registerFeatures(app_path('../features'), 'App\\Features'); } }
For a package, add it to your package's main service provider:
use Edalzell\Features\Concerns\HasFeatures; class MyPackageServiceProvider extends ServiceProvider { use HasFeatures; public function register(): void { $this->registerFeatures(); } }
In a package, registerFeatures() defaults to looking in <package-root>/features/ and registering providers under YourPackage\Features\FeatureName\ServiceProvider. Pass explicit arguments to override either default:
$this->registerFeatures('/path/to/features', 'My\\Namespace\\Features');
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
License
The MIT License (MIT). Please see License File for more information.