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

Laravel Composer Laravel Package

rinvex/laravel-composer

Rinvex Composer integrates Composer package management into Laravel, letting you inspect installed packages and run dependency operations programmatically from your application. A lightweight wrapper for managing Composer workflows without leaving PHP.

View on GitHub
Deep Wiki
Context7

Getting Started

Prerequisites: Composer 2.x and PHP 7.4+ (verify exact bounds in the plugin's composer.json — the package is archived and predates PHP 8.2/Composer 2.5 in places). Because it is a Composer plugin, it must be a real dependency of the root project (or installed globally) — it will never run from a transitive dependency.

1. Require the plugin

composer require --dev rinvex/laravel-composer

Use --dev unless your install-time scripts are required in production images.

2. Allow it to execute (Composer 2.2+ mandatory)

Without this Composer blocks the plugin and it silently does nothing:

{
    "config": {
        "allow-plugins": {
            "rinvex/laravel-composer": true
        }
    }
}

3. Look here first, in this order

  1. The plugin class in src/ that implements Composer\Plugin\PluginInterface and EventSubscriberInterface — this is the authoritative list of events it listens to and the exact extra keys it reads. Since the repo is archived, the source is the documentation.
  2. The README.md usage block for the extra schema.
  3. composer.json → extra.class, which tells you how the plugin is bootstrapped and therefore how to fork/subclass it.

4. First use case — install a package outside vendor/

{
    "extra": {
        "rinvex-composer": {
            "installer-paths": {
                "modules/Blog": ["acme/blog-module"],
                "modules/Shop": ["acme/shop-module"]
            }
        }
    }
}

Then:

composer install -vvv
ls modules/Blog   # should exist instead of vendor/acme/blog-module

If nothing happens, you have an allow-plugins, key-name, or event-matching problem — see Gotchas.

5. Second use case — lifecycle hooks

Attach shell work to post-install-cmd / post-update-cmd / post-uninstall-cmd so module wiring (asset publishing, cache clearing, .env scaffolding) happens automatically after a package moves in or out.


Implementation Patterns

Modular monolith with modules/

The primary day-to-day leverage: keep first-party or vendored modules in a readable modules/ tree while still installing them via Composer (so composer.json, version constraints, and the lock file stay the source of truth). Combine with Laravel's package discovery by giving each module a composer.json with:

"extra": {
    "laravel": { "providers": ["Acme\\Blog\\BlogServiceProvider"] }
}

Then register the module namespace in the root composer.json autoload, because Composer no longer owns that path:

"autoload": { "psr-4": { "Acme\\Blog\\": "modules/Blog/src/" } }

Hook scripts as "install-time bootstrap"

Treat the plugin's script support as a post-install orchestrator and keep it idempotent and non-interactive:

"scripts": {
    "post-install-cmd": [
        "@php artisan vendor:publish --tag=acme-config --force",
        "@php artisan optimize:clear"
    ]
}

Rules that keep this sane:

  • Never run migrations or seeding automatically in post-install-cmd — use post-update-cmd gated on --no-dev, or better, an explicit Artisan command.
  • Guard with test -f artisan if the project may install outside a Laravel root (CI scaffolding, tooling repos).
  • Prefer @php over bare php so the Composer runtime's binary is reused.

Environment parity in CI

Composer plugins are skipped in --no-plugins mode. If your CI uses composer install --no-plugins --no-scripts for speed/security, modules will land in vendor/ and your build breaks. Either:

  • drop --no-plugins for the build stage and keep --no-scripts for untrusted contributions, or
  • pre-checkout the modules/ tree and validate it separately.

Document the choice in the CI file — this is the #1 thing that surprises teammates.

Local development against a module

Pair the plugin with a path repository so you get a symlink into modules/ with live editing:

"repositories": [{ "type": "path", "url": "modules/Blog", "options": { "symlink": true } }]

This is the pattern that actually makes the package worth using — you get Composer's dependency resolution and a normal source tree in your IDE.

Team onboarding checklist

Because behavior is invisible until it isn't, add to README/CONTRIBUTING:

  1. composer config allow-plugins.rinvex/laravel-composer true
  2. composer install (not --no-plugins)
  3. What lives in modules/ vs vendor/
  4. How to recover: rm -rf modules vendor composer.lock && composer install

Extension points

To customize behavior without patching an archived package:

  • Fork and bump "extra": { "class": "Your\\Plugin" } — wait, that key belongs to the plugin's own composer.json, so a fork is the only way to point at your class.
  • Simpler: keep the package for its install-path behavior and move all orchestration into plain scripts in your root composer.json, which you control and can version independently.

Gotchas and Tips

It does nothing until allowed

Composer 2.2+ blocks unlisted plugins. Symptom: composer install succeeds, no module directory appears, no warning you'd notice among the output. Check:

composer diagnose
composer config --list | grep -i allow-plugins

Archived — pin it hard

11 stars and archived means: no security patches, no Composer 3 support, no PHP 8.3+ guarantees. Mitigate by pinning an exact version and committing the lock file:

"require-dev": { "rinvex/laravel-composer": "1.x.y" }

Consider vendoring the plugin into a private VCS repo or forking before the next Composer major.

Autoloading is not handled for you

Moving a package out of vendor/ does not add it to Composer's generated autoloader. You must either declare the namespace in root autoload.psr-4 or require a stub that require_onces the module's entry point. Forgetting this produces "Class not found" errors at runtime that look like a Laravel discovery failure — they aren't.

composer update can move or resurrect paths

If a package is removed from installer-paths, the old directory may be orphaned (left behind) or overwritten. Don't hand-edit files inside modules/ for third-party code; treat those directories as install artifacts and .gitignore them, or convert them to path repositories if you intend to edit.

Event ordering and uninstall

post-uninstall-cmd runs after the package files are gone on modern Composer. Any script that needs the package's code (e.g. a cleanup Artisan command defined by that very package) will fail. Capture what you need at pre-uninstall-cmd or make cleanup self-contained shell.

Scripts run without Laravel bootstrapped

The plugin executes during Composer's lifecycle, not inside the framework. app(), facades, and Eloquent are unavailable unless your script boots artisan itself. Keep hook scripts to @php artisan ... invocations and filesystem/CWD-safe operations.

Windows and CWD

Relative paths in installer-paths and hook scripts resolve against the project root, but Windows separators and case-insensitivity bite. Standardize on forward slashes in config; verify on the CI matrix before trusting it.

Debugging recipe

composer install -vvv            # every listener and its payload
composer install 2>&1 | grep -i plugin
cat vendor/composer/installed.json | jq '.[] | select(.name|test("rinvex"))'

If the plugin is listed in installed.json but no hook output appears, you have an extra key mismatch — diff your key against the literal string in the plugin source, not against blog posts.

Lock-file consequences

The root composer.lock hashes the extra block of the root package in some Composer versions. Editing install paths without a subsequent composer update --lock can make installs non-reproducible across machines.

Don't reach for it as a general-purpose installer

composer/installers is maintained, handles installer types idiomatically, and has broad ecosystem support. If your only need is moving one package to a custom path, prefer composer/installers or a path repository; use this plugin only where you specifically need its combined "custom path + lifecycle script" behavior, and be prepared to migrate off it.

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.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route