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.
- ποΈ Flexible Module Generation - Customizable architecture patterns with sensible defaults
- β‘ Extensive Artisan Commands - Complete toolkit for rapid modular development
- π Auto-Discovery - Automatic module registration and loading
- π― Fully Customizable - Adapt any folder structure and architectural pattern
- π Developer Friendly - Simple commands with intelligent defaults
- ποΈ Clean Architecture Ready - Pre-configured templates for Domain, Application, Infrastructure, and Presentation layers
- π οΈ Development Toolkit - Optimized for development workflow with minimal production footprint
- π Laravel 12 Ready - Full compatibility with Laravel 12's latest features
- Laravel 12+ - Built specifically for Laravel 12
- PHP 8.2+ - Required by Laravel 12
- Composer - For package management
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
- π― Separation of Concerns: Each layer has specific responsibilities
- π Testability: Easy to unit test business logic in isolation
- π Scalability: Add features without affecting existing code
- π§ Maintainability: Clear structure for team collaboration
- π Independence: Domain logic independent of frameworks and databases
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:
- Registered in
bootstrap/providers.php
using Laravel's official method - Loaded on application startup
- Available immediately without manual configuration
// 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:
- Domain logic in isolated entities
- Database schema with dedicated migrations
- API endpoints with versioned resources
- Tests for reliable functionality
# Tenant-specific modules
php artisan easymodules:new Tenant Organization Billing Subscription
- ServiceProvider Auto-Registration - Uses Laravel 12's official
addProviderToBootstrapFile
method - All Essential Laravel Commands - Full compatibility with Laravel's core Artisan commands within modules
- PHP 8.2+ - Takes advantage of modern PHP features and syntax
- Enhanced Vite - Works with Laravel 12's improved asset compilation
- Framework Features - Complete integration with Laravel 12's core functionality
Laravel Easy Modules is designed specifically for Laravel 12 from the ground up - no migration needed, just clean modular development ready to use.
- Domain : Pure business logic, framework-independent
- Application : Use cases and orchestration logic
- Infrastructure : Persistence, external services, and technical details
- Presentation : User interface, APIs, and external communication
- Team Collaboration : Multiple developers can work on different modules
- Code Organization : Logical grouping by business functionality
- Reusability : Modules can be extracted as packages
- Testing : Isolated testing of business logic
- Independent Deployment : Modules can evolve separately
- Feature Isolation : New features don't affect existing modules
- Easier Debugging : Clear boundaries help identify issues
- Legacy Migration : Gradual modernization of existing applications
- π Command Guide - Complete reference for all commands
- π§ Configuration Guide - Advanced customization and architectural patterns
- ποΈ Architecture Templates - Future multi-pattern feature
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:
- EasyModules: Simple setup, structured defaults, future multi-pattern support, production-independent modules. EasyModules is a dev-tool only - no need to deploy it to production
- nWidart: Complete flexibility, manual configuration, established ecosystem
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.
- Kadevland - Creator and maintainer
- Contributors - Thank you for your contributions!
Made with β€οΈ by Kadevland
β Star us on GitHub if this project helps you!
Laravel Easy Modules - Flexible modular development made simple π