Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Modulr Laravel Package

zenphp/modulr

ZenPHP Modulr is a Laravel package for building modular applications. Organize features into self-contained modules with streamlined registration and discovery, helping keep large codebases structured, reusable, and easier to maintain.

View on GitHub
Deep Wiki
Context7

Getting Started

Modulr is a small, low-adoption Laravel package (1 star, no dependents) that adds modular application structure — splitting a Laravel app into self-contained modules with their own routes, migrations, views, config, and service providers. Because adoption is minimal, treat the README and the package source as the source of truth over any blog posts.

Minimal setup:

  1. Install

    composer require zenphp/modulr
    

    Confirm the package supports your Laravel version — check its composer.json illuminate/* constraints before committing. With no dependents and a single maintainer, version compatibility is the first thing to verify.

  2. Publish config and assets (typical for this class of package):

    php artisan vendor:publish --provider="ZenPHP\Modulr\ModulrServiceProvider"
    

    Inspect the published config/modulr.php — it usually defines the module path (e.g. app/Modules or Modules/), namespace, and whether modules are auto-discovered.

  3. Where to look first

    • config/modulr.php — module root path, namespace convention, discovery toggle.
    • The package's service provider — reveals auto-discovery behavior and registration order.
    • Any stubs/ directory — shows the canonical module skeleton, which tells you far more about intended structure than prose docs.
  4. First use case — create one module and move a single existing feature (a small CRUD: controller, routes, migration, views) into it. This verifies discovery, routing, and migration loading before you attempt a larger refactor.

php artisan modulr:make Blog     # name may differ; check `php artisan list | grep modulr`

Implementation Patterns

Module-per-feature, not module-per-layer. The value of Modulr appears when each module owns its full vertical slice: Blog/Http/Controllers, Blog/Routes/web.php, Blog/Database/Migrations, Blog/Resources/Views, Blog/Providers/BlogServiceProvider. Keep cross-module coupling explicit — modules should talk through events, contracts, or shared app/Support code, never by reaching into another module's internals.

Service provider as the module's contract. Each module should register its own routes, migrations, views, config, and translations in its provider. Follow Laravel's standard loadRoutesFrom, loadMigrationsFrom, loadViewsFrom, mergeConfigFrom calls — most modular packages rely on these under the hood, so if discovery ever misbehaves you can register manually.

Discovery vs. explicit registration. Prefer explicit registration in config/modulr.php (or a provider) over filesystem auto-discovery for production apps. Auto-discovery is convenient in development but produces surprising behavior when a directory is renamed, and it interacts poorly with config caching if the package doesn't hook into config:cache carefully.

Integration with existing Laravel conventions:

  • Routing: module routes typically mount under a prefix defined per module. Verify middleware groups and route-name collisions — two modules both defining posts.index will clash.
  • Migrations: confirm migration filenames are unique across modules (Laravel keys on filename). Prefix with the module name: 2024_01_01_000000_create_blog_posts_table.php.
  • Livewire/Inertia: if you use either, test that module views resolve — loadViewsFrom namespacing (blog::posts.index) is easy to get wrong.
  • Testing: point module tests at the module namespace; consider a Pest/PHPUnit setup that mirrors module structure so tests travel with features.

Workflow suggestion: migrate incrementally. Move one leaf feature per PR, run the full test suite, then delete the original files. This keeps git history clean and makes rollback trivial — important given the package's immaturity.

Gotchas and Tips

  • Config caching is the top suspect. Modular packages that scan directories frequently break under php artisan config:cache / route:cache because cached config snapshots the module list. After adding a module, always: php artisan optimize:clear then re-cache. If routes vanish in production, this is almost always why.
  • Autoloading must line up with namespaces. composer.json autoload.psr-4 must map the module namespace (e.g. "Modules\\": "Modules/" or "App\\Modules\\": "app/Modules/") exactly as the package expects. Mismatches produce "class not found" errors that look like discovery failures. Run composer dump-autoload after adding modules.
  • Namespace collisions. Two modules with a Models/User.php or the same route name will silently conflict. Adopt naming conventions early — module-prefixed route names and unique migration filenames.
  • Migrations run globally, not per-module. There is usually no --module flag on migrate. Verify that migrate:fresh and migrate:rollback pick up module migrations; test in a scratch database before trusting it in CI.
  • Facade/config access. If the package exposes a Modulr facade, avoid it in controllers — inject or resolve via the container so tests can fake it. Config keys read via config('modulr.…') should be cached at boot, not per-request.
  • Debugging checklist when a module isn't loading:
    1. php artisan optimize:clear
    2. composer dump-autoload
    3. Is the module listed in config / discoverable at the configured path?
    4. Does its provider extend the right base and is it registered?
    5. php artisan route:list | grep <module> to confirm routes mounted.
  • Extension points are thin. With a 1-star package, expect limited hooks. Fork or vendor the package if you need custom discovery logic; pin the version in composer.json and watch for the next release (2026-05-06) since breaking changes are plausible pre-1.0.
  • Bus factor. Single maintainer, no dependents. If Modulr is load-bearing for your architecture, keep a thin internal wrapper around its registration so you can swap to a more established modular package or hand-rolled providers without rewriting every module.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib