keljtanoski/modular-laravel
Modular Laravel helps organize Laravel applications into reusable modules. It provides structure and commands for creating modules with their own routes, migrations, views, and service providers, keeping large codebases clean, maintainable, and easier to scale.
This is a starter template, not an installable library — you don't composer require it into an existing app. You adopt the whole skeleton:
composer create-project keljtanoski/modular-laravel my-app
# or: git clone … && composer install
cp .env.example .env && php artisan key:generate
# set DB creds, then:
php artisan migrate
Look here first, in this order:
composer.json — confirm the Laravel/PHP versions it was pinned to (last release Feb 2023, so expect Laravel 9/10-era constraints). This tells you how much upgrading you're signing up for.Modules/ or app/Modules/) — this is the heart of the template. Read one complete example module end-to-end before writing anything.composer.json autoload.psr-4 — verify the module namespace mapping (e.g. "Modules\\": "Modules/"). Everything depends on this.First use case: build one small vertical slice (e.g. a Billing module) by copying the example module folder, renaming the namespace, registering its provider, and running php artisan migrate. That single exercise teaches you 90% of the template's conventions.
One module = one bounded context. Keep controllers, models, migrations, routes, views, config, and tests co-located inside the module folder. Resist the urge to leak a module's Eloquent models into another module.
Per-module service provider is the integration seam. A typical module provider does the heavy lifting:
public function register(): void
{
$this->mergeConfigFrom(__DIR__.'/Config/billing.php', 'billing');
}
public function boot(): void
{
$this->loadRoutesFrom(__DIR__.'/Routes/web.php');
$this->loadRoutesFrom(__DIR__.'/Routes/api.php');
$this->loadMigrationsFrom(__DIR__.'/Database/Migrations');
$this->loadViewsFrom(__DIR__.'/Resources/views', 'billing');
$this->loadTranslationsFrom(__DIR__.'/Resources/lang', 'billing');
}
Register that provider in config/app.php (or whatever module loader the template uses). If the template follows nwidart/laravel-modules conventions, prefer php artisan module:make Billing and module:make-provider over hand-copying folders.
Feature workflow, day to day:
Routes/web.php / api.php, applying prefix and middleware inside the provider rather than repeating them per route.php artisan migrate.Tests/ folder.composer dump-autoload if you added a brand-new namespace.Cross-module communication: prefer Laravel events/listeners or interfaces bound in providers over direct class references. If module A needs module B, depend on a contract (BillingGateway) and bind the implementation in the provider — this keeps modules swappable and testable in isolation.
Config: keep module-specific config in Config/<module>.php and expose it via mergeConfigFrom. Consumers then use config('billing.something') rather than reaching into the module.
create-project, you own every line. Diff against fresh Laravel releases manually and budget for a Laravel upgrade early — a Feb 2023 skeleton will be several minor versions behind.composer dump-autoload. If you get "class not found" on a module class, check the PSR-4 mapping and run the dump before debugging anything else.route:cache and config:cache break module code. Route files must be closure-free to cache cleanly. Per-module config that isn't mergeConfigFrom'd will silently disappear under config:cache.billing_invoices, not invoices) and keep timestamps sane.php artisan route:list.loadMigrationsFrom() pointing at the right path?loadViewsFrom()?null → did you call mergeConfigFrom() in register(), not boot()?register() vs boot(). Config merging and container bindings go in register(); anything that touches routes, events, or other providers goes in boot().extra.laravel discovery. Copying folders is fine for one project; it rots across many.composer audit before shipping and bump transitive dependencies as needed.How can I help you explore Laravel packages today?