unusualify/modularity
Unusualify Modularity is a Laravel package for building modular applications with reusable, self-contained modules. It provides module discovery, service provider registration, config and route loading, and a structured foundation for organizing large Laravel projects into maintainable packages.
composer require unusualify/modularous
php artisan modularous:install # publishes config, migrations, assets
php artisan migrate
config/modularous.php (auth guard, admin route prefix, media/translation toggles) and the generated modules/ directory — Modularous keeps almost everything per-module rather than in app/.php artisan modularous:make:module Post
php artisan modularous:make:crud Post --model=Post
This generates the model, repository, controller, requests, routes, migrations, and the Vue admin screens under the module's resources/js folder.getFormFields() on the module's controller/repository, and confirm the Vue form renders and saves. That single loop (PHP field definition → Vue form → submit) is the core of day-to-day work with this package.Module-first structure. Treat each module as a small Laravel app: Routes/, Http/Controllers, Repositories, Models, Database/Migrations, Resources/js. Register cross-module behaviour through service providers in the module rather than editing the host app.
Repository traits over fat controllers. Controllers stay thin; behaviour lives in repository traits (HasCRUD, HasValidation, HasMedia, HasTranslation, HasPosition, HasSlug, etc.). Compose them on the repository and let the base controller call through. When you need new behaviour, add a trait and attach it — don't override the controller's submit.
Form definition in PHP, rendering in Vue. Fields, validation rules, and defaults are declared server-side (form field classes returned from getFormFields()), and the Vue form builder renders them. This keeps validation rules and UI in sync — a good rule of thumb is: if a field matters, it should be declared in PHP, not hand-written in the Vue template.
Submit and async flow. The submit path is the workhorse: it validates the payload, persists via the repository, and returns a JSON response the Vue layer consumes. On the frontend, wrap calls in try/catch, expect 422 for validation failures with an errors object keyed by field name, and keep a loading flag tied to the awaited promise. Recent 12.x patches hardened this method (validation + async handling), so if you have custom overrides of submit, re-test them against the new behaviour after upgrading.
Listing and filtering. Index data goes through the repository's datatable method; add filters by extending the repository query and declaring the filter in the module's listing config rather than adding controller logic.
Routes per module. Module routes are namespaced and auto-loaded; add custom endpoints in the module's route file with the same middleware stack as the generated CRUD routes so auth/permissions stay consistent.
Payment services as a pluggable concern. Payment handling is delegated to payment-service classes rather than hard-coded in controllers. If a module offers checkout, model it as a selectable service so deployments can enable/disable providers independently — and always guard the "no card provider configured" path (see Gotchas).
php artisan optimize:clear (and re-run modularous:install-style asset publishing if the admin UI doesn't reflect changes). Stale compiled assets are the most common "my change did nothing" cause.create() or getIndexData() behaves unexpectedly, check which trait actually wins before debugging the caller.422 appears with an empty error bag, check that the field name in the Vue form matches the PHP key exactly.posts, post_translations, …).submit path or the frontend form binding. Laravel Telescope on the admin routes is the fastest way to see the actual payload and validation response.resources/js (the admin build aliases module components ahead of the package's). Anything you patch in vendor/unusualify/modularous will be lost on the next composer update.How can I help you explore Laravel packages today?