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

Module Manager Laravel Package

liberusoftware/module-manager

A Laravel package for managing modular application components: register, enable, disable, and organize modules with their service providers, routes, migrations, and configuration. Helps simplify building and maintaining modular Laravel applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package and publish its configuration:

composer require liberusoftware/module-manager
php artisan vendor:publish --provider="Liberu\ModuleManager\ModuleManagerServiceProvider" --tag=config

Because this package is new (0 stars, no dependents, release dated in the future), treat the API surface as unstable. After installing, immediately run php artisan list and grep for module-related commands to confirm the actual command names and signatures before scripting against them:

php artisan list | grep -i module

First use case — manifest discovery. Create a manifest at the root of a module directory (typically modules/ or app/Modules/, depending on how the package's discovery paths are configured):

{
  "name": "acme/reports",
  "description": "Reporting module",
  "providers": ["Acme\\Reports\\ReportsServiceProvider"],
  "requires": {
    "acme/core": "^1.0"
  },
  "enabled": true
}

Then run discovery to populate the registry:

php artisan module:discover
php artisan module:list

The first real win is replacing hand-maintained provider arrays in config/app.php with manifest-driven registration. Once module:list shows your module, enable it and confirm its routes, migrations, and commands are picked up:

php artisan module:enable acme/reports
php artisan route:list | grep reports

Where to look first:

  1. The published config file — discovery paths, cache store, and enablement strategy live here.
  2. The manifest schema — if the package ships a JSON schema or DTO, read it; that defines the contract you'll be authoring against.
  3. The diagnostics command — run it early to get a baseline of what the package considers healthy.

Implementation Patterns

Manifest-per-module with explicit dependencies. Define requires in each manifest and let the resolver compute boot order. This replaces brittle ordering conventions like naming directories 01-core, 02-reporting. Keep dependency constraints semver-style (^1.0) so resolution failures surface at deploy time rather than as a Class not found at runtime.

Environment-scoped enablement. "Deployment enablement" suggests enable/disable state is persisted separately from manifests. Use this to keep dev-only modules (seeders, debug toolbars, local fixtures) out of production without editing manifests per environment:

// In a deploy script or CI step
Artisan::call('module:enable', ['module' => 'acme/debug-tools']); // local
Artisan::call('module:disable', ['module' => 'acme/debug-tools']); // production

If enablement state lives in the database, back it with a migration and seed the production set deterministically — do not rely on developers toggling state by hand.

Registry caching in the deploy pipeline. Discovery (filesystem scans + manifest parsing) is the expensive step. Warm the cache as part of deploy, after composer install and before config:cache:

composer install --no-dev --optimize-autoloader
php artisan module:discover
php artisan module:cache        # if the package exposes an explicit warm command
php artisan config:cache
php artisan route:cache
php artisan module:diagnose     # fail the build on unresolved deps

Treat module:diagnose as a CI gate. Its non-zero exit code (if provided) is worth wiring into your pipeline so a broken manifest fails fast rather than producing a half-booted app.

Programmatic resolution via facade or container binding. For code that needs to know what's installed — feature toggles, navigation builders, admin dashboards — resolve through the package rather than scanning the filesystem yourself:

$modules = Module::all();                 // depends on actual facade name
$enabled = Module::enabled();
$ordered = Module::resolve(['acme/reports']); // dependency-sorted

Cache the result per request if you call it in a loop; registry lookups may hit the cache store each time.

Diagnostics as a developer onboarding tool. Run module:diagnose (or equivalent) when a new developer clones the repo. It should reveal missing manifests, unresolvable constraints, and stale cache in one shot — considerably faster than the usual "why isn't my provider loading" archaeology.

Gotchas and Tips

  • The cache is the source of truth at runtime, not the filesystem. Editing a manifest without re-running discovery/cache warm will silently do nothing. Bake a module:clear or re-discover step into any workflow that adds or edits manifests, and document it for the team.
  • Deployment enablement ≠ autoloading. Enabling a module does not make its classes autoloadable; Composer's PSR-4 mapping still governs that. If a module's namespace isn't in composer.json, enablement succeeds but the provider fails to instantiate. Register module namespaces in composer.json (or use a path repository) before wiring enablement.
  • Circular dependencies need a clear failure mode. Test what happens with A requires B and B requires A — confirm the resolver throws a legible exception rather than looping or silently dropping one module. Add this as a deliberate negative test in your suite.
  • Cache store config matters in multi-server setups. If the registry cache defaults to file, per-node caches diverge in a load-balanced deploy. Point it at Redis (or whatever shared store you already run) via the published config, and warm once in the deploy rather than on first request per node.
  • Boot order is load-bearing for service providers. If two modules register competing bindings or event listeners, dependency order determines the winner. Keep cross-module coupling in requires rather than relying on incidental discovery order — filesystem ordering is not a contract.
  • Version pinning is mandatory right now. With zero dependents and a future-dated release, there's no ecosystem pressure to keep the API stable. Pin an exact version in composer.json (not ^), and review the changelog before bumping. Vendor the package or fork it if the manifest format is central to your architecture.
  • Extension points to watch for: custom manifest fields (if unknown keys are preserved, they make a good home for app-specific metadata like navigation entries or feature flags) and any resolver/strategy interfaces the package exposes. Prefer these over forking.
  • Verify diagnostics output is machine-readable before parsing it in CI — if it emits human-formatted text, capture the exit code only rather than grepping, and keep the regex-free path.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource