kadevland/laravel-easy-modules
Package Status: This package has been tested and works correctly for most use cases. However, some edge cases may require manual handling depending on your specific setup.
Laravel Easy Modules is a flexible Laravel package that enables you to organize your application using modular architecture. Generate organized, maintainable applications with automatic component registration and structured code separation. Clean Architecture templates are provided as sensible defaults, but fully customizable to your needs.
Install via Composer:
composer require --dev kadevland/laravel-easy-modules
Publish configuration:
# Default way
php artisan vendor:publish --provider="Kadevland\EasyModules\EasyModulesServiceProvider" --tag="config"
# Using Laravel Easy Modules command
php artisan easymodules:publish
# Publish with options
php artisan easymodules:publish --all # Config & stubs
php artisan easymodules:publish --stubs # Stubs only
php artisan easymodules:publish --force # Force overwrite
Create your first module:
# Single module
php artisan easymodules:new Blog
# Multiple modules
php artisan easymodules:new Blog User Product
# Using aliases
php artisan emodules:new Shop
php artisan emodule:new Auth
When you run php artisan easymodules:new Blog, you get a complete Clean Architecture structure by default, but this is fully customizable to match your preferred architecture pattern:
📝 Note: This structure is just the default template. You can completely customize the folder structure, paths, and architectural patterns through configuration. See Configuration Guide for details.
app/Modules/Blog/
├── 📁 Application/ # 🎯 Use Cases & Business Logic
│ ├── Actions/ # Use case implementations
│ ├── DTOs/ # Data Transfer Objects
│ ├── Interfaces/ # Contracts and interfaces
│ ├── Mappers/ # Data transformation logic
│ ├── Rules/ # Business rules validation
│ ├── Services/ # Application services
│ └── Validation/ # Input validation logic
├── 📁 Domain/ # 🧠 Core Business Logic
│ ├── Entities/ # Domain entities (business models)
│ ├── Services/ # Domain services (business logic)
│ └── ValueObjects/ # Value objects used in entities
├── 📁 Infrastructure/ # 🏛️ External Concerns
│ ├── Casts/ # Custom Eloquent casts
│ ├── Events/ # Application events
│ ├── Exceptions/ # Custom exceptions for error handling
│ ├── Jobs/ # Queue jobs and background tasks
│ ├── Listeners/ # Event listeners
│ ├── Mail/ # Mailable classes
│ ├── Mappers/ # Entity ↔ Model transformation
│ ├── Models/ # Eloquent models (database persistence)
│ ├── Notifications/ # Notification classes
│ ├── Observers/ # Model observers
│ ├── Persistences/ # Repositories and data access
│ ├── Policies/ # Authorization policies
│ ├── Rules/ # Validation rules
│ └── Services/ # External services integration
├── 📁 Presentation/ # 🎨 User Interface
│ ├── Console/Commands/ # Custom Artisan commands
│ ├── Http/Controllers/ # HTTP controllers for request handling
│ ├── Http/Middlewares/ # HTTP middleware
│ ├── Http/Requests/ # Form requests for validation
│ ├── Http/Resources/ # API resources for response formatting
│ ├── Mappers/ # Display-related transformations
│ ├── Views/Components/ # Blade components for UI
│ └── resources/views/ # Blade templates
├── 📁 Database/ # 🗄️ Database Related
│ ├── Factories/ # Model factories for testing
│ ├── Migrations/ # Database schema management
│ └── Seeders/ # Database seeders
├── 📁 Tests/ # 🧪 Testing
│ ├── Feature/ # Integration/Feature tests
│ └── Unit/ # Unit testing
├── 📁 Providers/ # 🔧 Service Providers
│ └── BlogServiceProvider.php # Auto-generated and registered
├── 📁 config/ # ⚙️ Configuration
│ └── config.php # Module-specific configuration
├── 📁 routes/ # 🛣️ Route Definitions
│ ├── web.php # Web routes (with examples)
│ ├── api.php # API routes (with examples)
│ └── console.php # Console routes (with examples)
└── 📁 lang/ # 🌍 Translations
Laravel Easy Modules provides an extensive command toolkit for rapid development:
👉 Complete Command Reference Guide - Full documentation with examples
# Create a complete blog module
php artisan easymodules:new Blog
# Generate domain components
php artisan easymodules:make-entity Blog Post
# Use familiar Laravel commands in modules
php artisan easymodules:make-model Blog Post --migration --factory
# Flexible component generation with custom stubs
php artisan easymodules:make-stub Blog UserRepository repository
php artisan easymodules:make-stub Shop OrderDTO dto
php artisan easymodules:make-stub User EmailValueObject valueobject
# Get detailed module information
php artisan easymodules:info Blog
# List discovered modules
php artisan easymodules:list --routes
All commands support these prefixes for convenience:
easymodules: (full)emodules: (short)emodule: (shortest)Laravel Easy Modules leverages Laravel 12's enhanced auto-discovery features for seamless integration:
When auto_discover = true, newly created modules are automatically:
bootstrap/providers.php using Laravel's official method// bootstrap/providers.php (automatically updated)
return [
App\Providers\AppServiceProvider::class,
App\Modules\Blog\Providers\BlogServiceProvider::class, // ← Auto-added
];
You can also register modules manually by adding them directly to bootstrap/providers.php:
// bootstrap/providers.php
return [
App\Providers\AppServiceProvider::class,
App\Modules\Blog\Providers\BlogServiceProvider::class,
App\Modules\User\Providers\UserServiceProvider::class,
// Add your modules here
];
To disable a module, simply remove or comment its ServiceProvider from bootstrap/providers.php:
// bootstrap/providers.php
return [
App\Providers\AppServiceProvider::class,
// App\Modules\Blog\Providers\BlogServiceProvider::class, // ← Disabled
App\Modules\User\Providers\UserServiceProvider::class,
];
Important: All generated code remains fully functional even if you remove Laravel Easy Modules package. Each module generated uses standard Laravel ServiceProvider patterns and can operate independently.
View all modules discovered by the auto-discovery system:
# View all discovered modules with detailed information
php artisan easymodules:list --routes
Example output:
📋 Laravel Easy Modules - Module Discovery
📁 Base Path: /app/Modules
📦 Base Namespace: App\Modules
🔍 Auto-Discovery: ✅ Enabled
+---------+------------------+---------------------+-----+-----+---------+
| Module | Path | Provider | Web | API | Console |
+---------+------------------+---------------------+-----+-----+---------+
| Blog | /app/Modules/Blog| BlogServiceProvider | ✅ | ✅ | ❌ |
| User | /app/Modules/User| UserServiceProvider | ✅ | ❌ | ❌ |
| Shop | /app/Modules/Shop| ShopServiceProvider | ✅ | ✅ | ✅ |
+---------+------------------+---------------------+-----+-----+---------+
📊 Summary:
Total modules: 3
With web routes: 3
With API routes: 2
With console routes: 1
Customize module generation in config/easymodules.php:
return [
// Module location and namespace
'base_path' => app_path('Modules'),
'base_namespace' => 'App\\Modules',
// Laravel 12 auto-discovery
'auto_discover' => true,
// Custom paths per component
'paths' => [
'controller' => 'Presentation/Http/Controllers',
'model' => 'Infrastructure/Models',
'entity' => 'Domain/Entities',
// ... fully customizable
],
// Custom stubs for flexible architecture
'stubs' => [
'controller' => 'easymodules/controller.stub',
'entity' => 'easymodules/entity.stub',
'dto' => 'easymodules/dto.stub',
'repository' => 'easymodules/repository.stub',
// ... your custom templates
]
];
Each module can have its own configuration for module-specific settings:
// app/Modules/Blog/config/config.php
return [
'name' => 'Blog',
'enabled' => true,
// Your custom settings
'posts_per_page' => 10,
'cache_ttl' => 3600,
'features' => [
'comments' => true,
'categories' => true,
'seo' => true,
],
'seo' => [
'meta_length' => 160,
'slug_separator' => '-',
],
];
// Access in your code
config('blog.posts_per_page'); // 10
config('blog.features.comments'); // true
# Publish stubs for customization
php artisan easymodules:publish --stubs
# Modify in resources/stubs/easymodules/
# Create your own architectural patterns
Important: No stubs are provided by default - you create them according to your architectural needs using the make-stub system.
Add to your phpunit.xml:
<testsuites>
<testsuite name="Feature">
<directory suffix="Test.php">./tests/Feature</directory>
<directory suffix="Test.php">./app/Modules/*/Tests/Feature</directory>
</testsuite>
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>
<directory suffix="Test.php">./app/Modules/*/Tests/Unit</directory>
</testsuite>
</testsuites>
Add to your tests/Pest.php:
uses(Tests\TestCase::class)->in('Feature', 'Unit');
uses(Tests\TestCase::class)->in('app/Modules/*/Tests/Feature');
uses(Tests\TestCase::class)->in('app/Modules/*/Tests/Unit');
Laravel 12 uses enhanced Vite configuration. Update your vite.config.js:
import { defineConfig } from "vite";
import laravel from "laravel-vite-plugin";
import tailwindcss from "@tailwindcss/vite";
import { glob } from "glob";
// Auto-discovery of module assets
const moduleAssets = [
...glob.sync("app/Modules/*/Presentation/resources/js/**/*.js"),
...glob.sync("app/Modules/*/Presentation/resources/css/**/*.css"),
...glob.sync("app/Modules/*/Presentation/resources/scss/**/*.scss"),
];
export default defineConfig({
plugins: [
laravel({
input: [
"resources/css/app.css",
"resources/js/app.js",
...moduleAssets, // Auto-discovered module assets
],
refresh: [
// Default Laravel refresh
"resources/views/**",
"routes/**",
"app/**",
// Module-specific refresh
"app/Modules/*/Presentation/resources/views/**",
"app/Modules/*/Presentation/Views/Components/**",
"app/Modules/*/routes/**",
],
}),
tailwindcss(), // Laravel 12 Tailwind plugin
],
resolve: {
alias: {
"@": "/resources/js",
"@modules": "/app/Modules",
},
},
});
Required installation:
npm install glob --save-dev
Update your tailwind.config.js for module support:
export default {
content: [
"./resources/**/*.blade.php",
"./resources/**/*.js",
"./resources/**/*.vue",
"./app/**/*.php",
// Laravel Easy Modules with Clean Architecture
"./app/Modules/*/Presentation/resources/views/**/*.blade.php",
"./app/Modules/*/Presentation/resources/**/*.js",
"./app/Modules/*/Presentation/resources/**/*.vue",
"./app/Modules/*/Presentation/Views/Components/**/*.php",
],
theme: {
extend: {},
},
plugins: [],
};
php artisan easymodules:new Blog
// app/Modules/Blog/config/config.php
return [
'name' => 'Blog',
'enabled' => true,
'posts_per_page' => 15,
'cache' => [
'posts_ttl' => 3600,
'categories_ttl' => 7200,
],
'features' => [
'comments' => true,
'tags' => true,
'seo' => true,
'social_sharing' => true,
],
'seo' => [
'meta_description_length' => 160,
'slug_separator' => '-',
'auto_generate_meta' => true,
],
];
# Create separate modules for clean domain separation
php artisan easymodules:new Product Order Payment User Cart Inventory
Each module maintains its own:
# Tenant-specific modules
php artisan easymodules:new Tenant Organization Billing Subscription
addProviderToBootstrapFile methodLaravel Easy Modules is designed specifically for Laravel 12 from the ground up - no migration needed, just clean modular development ready to use.
If you're looking for modular Laravel development solutions, you might also consider:
A well-established and highly configurable module system for Laravel. Great choice if you prefer maximum flexibility and don't mind setting up your own structure from scratch.
EasyModules vs nWidart:
Both packages serve the modular development community well - choose based on whether you prefer structured defaults (EasyModules) or complete configurability (nWidart).
We created EasyModules because modular development should be simple, fast, and completely independent - remove EasyModules anytime, your code keeps running.
EasyModules believes in empowering developers without creating dependencies. We're here to help you design and scaffold beautiful, maintainable modular architectures using Laravel standards - then we disappear.
Configuration is simple by design. A single config file, clear folder structures, and intelligent defaults get you productive in minutes. No complex setup, no scattered configuration files, no learning curve.
Generated code is entirely yours to modify. EasyModules doesn't check, validate, or enforce anything after generation. Refactor freely, change structures, adapt to your needs - we're here to help, not to impose.
Generated modules are entirely yours. Built with standard Laravel patterns. No vendor lock-in - you choose how to manage your dependencies. Just clean, organized code that lives and breathes Laravel.
"We help you build it right, then get out of your way."
Contributions are welcome! Please see contributing guide.
Please see CHANGELOG for more information on recent changes.
For security issues, please email [email protected].
Open-source package under MIT license.
Made with ❤️ by Kadevland
⭐ Star us on GitHub if this project helps you!
Laravel Easy Modules - Flexible modular development made simple 🚀
How can I help you explore Laravel packages today?