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

Composer Dropin Installer Laravel Package

koodimonni/composer-dropin-installer

Composer plugin for Drupal that installs contributed modules, themes, and libraries into the correct project directories as drop-in packages. It simplifies dependency management for Drupal sites by letting Composer fetch and place code where Drupal expects it, reducing manual downloads and keeping b...

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Composer plugin, not a runtime library. Nothing ends up in your autoloader; its only job is to run during composer install/update and copy files from packages into paths you specify — and to skip the copy if the destination already exists. That "seed once, never clobber" behavior is the whole value proposition, so treat it as a deploy-time file placement tool, not a package manager feature.

Minimal setup:

  1. Require it as a real dependency (not require-dev — see Gotchas):
    composer require koodimonni/composer-dropin-installer
    
  2. Composer 2.2+ blocks plugins by default. Approve it in the root composer.json:
    "config": {
      "allow-plugins": {
        "koodimonni/composer-dropin-installer": true
      }
    }
    
  3. Declare what goes where in the root extra.dropin-paths, then run composer install and confirm the file landed and that a second run does not overwrite a file you edited.

First use case to prove it out: a caching plugin that ships object-cache.php. You want that file in wp-content/ on first install, but once a developer has hand-tuned it you never want Composer replacing it. Map wp-content/object-cache.php to the providing package, run the install, edit the file, run composer install again, and verify your edit survived. That single loop is the entire mental model for the package.

For Laravel shops the same logic applies to files an application is expected to own afterwards: a public/.htaccess variant, a phpunit.xml or .php-cs-fixer.php stub from a shared dev-tools package, Docker/compose files, or a CI config. Anything php artisan vendor:publish handles badly because the file is supposed to drift from the package version is a candidate.

Implementation Patterns

Root-project mapping (the common pattern). The root project owns the policy; packages don't need to know anything:

"extra": {
  "dropin-paths": {
    "wp-content/object-cache.php":    ["acme/redis-object-cache"],
    "wp-content/advanced-cache.php":  ["acme/page-cache"],
    "public/.htaccess":               ["acme/laravel-server-config"]
  }
}

Package-declared drops. If a package ships a dropin type and its own path config, the installer intercepts it so consumers get the file with zero configuration. Useful for internal packages where you control both ends; use the root mapping when consuming third-party packages.

Whole-directory vs. single files. "A few files from a package" is the interesting mode: you can pull one artifact out of a package that otherwise installs normally as a library. That lets a library ship an optional drop-in without forcing a custom type.

Bedrock / Trellis-style layouts. These projects already relocate wp-content; drop-ins are the classic case that composer/installers doesn't cover because they live at hardcoded paths (wp-content/object-cache.php, wp-content/db.php) rather than in a package directory. This plugin slots in next to composer/installers without conflict — keep installer-paths for plugins/themes and dropin-paths for the loose files.

Deploy workflow. Commit the mapping, let CI run composer install --no-dev --optimize-autoloader, and verify the drop-ins exist post-install. Because the plugin skips existing files, the first deploy to a new environment is when the copy actually happens — make that an explicit assertion in your deploy script rather than assuming it silently worked.

Upgrade path for a modified drop-in. Since existing files are never overwritten, upgrading the underlying package means: delete the drop-in (or move it aside), run composer install, diff the new stock file against your customization, and re-apply. Script this if you have more than a couple of drop-ins.

Gotchas and Tips

  • allow-plugins is mandatory on Composer 2.2+. Without it the plugin is silently not loaded and nothing gets copied — no error, just a missing file. It's the single most common "it doesn't work" cause.
  • Put it in require, not require-dev. Plugins in require-dev aren't installed when you run composer install --no-dev in production, so the drop-ins won't be placed on the deploy that needs them most.
  • Skip-if-exists means updates never propagate. After the first install the plugin is a no-op for that path forever. If you expected composer update to refresh a drop-in, it won't. Plan the manual delete-and-rediff cycle.
  • Uninstalls likely leave files behind by design. Don't expect composer remove to clean up paths — deletion would defeat the safety guarantee. Clean up manually and document it.
  • Path resolution and trailing slashes. Paths are resolved relative to the Composer working directory (project root), not the vendor dir. Inconsistent trailing slashes or a path that resolves outside the project will either miss or place files somewhere surprising — test with composer install -vvv and watch for the installer's copy messages.
  • Don't confuse it with composer/installers. installer-paths matches on package type and relocates the whole package; dropin-paths targets individual files/paths. Mixing the two up produces packages installed in the wrong place, not an error.
  • Package type must be one the installer supports for the package-declared mode; a plain library won't be intercepted, so use the root-project mapping instead.
  • Debugging: composer install -vvv and composer diagnose. If a file isn't appearing, check in order: plugin approved, plugin in require, path correct, destination not already present (that's the silent success case).
  • Maintenance risk is real. 48 stars, zero dependents, WTFPL, and a narrow single-purpose plugin. Pin an exact version, keep the mapping in version control, and be prepared to vendor/fork it or replace it with a small post-install-cmd PHP script (if (!file_exists($dest)) copy(...)) — the behavior is ~20 lines and you may prefer owning it. WTFPL is permissive but will still trigger a legal review at most companies; flag it before it lands in a commercial dependency graph.
  • Extension points are thin. There's no event system for post-copy hooks; if you need to chmod, patch, or template the file after placement, do it in a Composer script (post-install-cmd / post-update-cmd) that runs after the plugin.
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.
mydnic/volet-feature-board-filament-plugin
wmde/email-address
refinery29/test-util
dees040/laravel-api-responses
teamzac/geocoder
ideatica/config-writer
keaton-php/pipe-dream
jacksonwebservices/laravel-user-suite
maksimru/conditional-laravel-debugbar
gismatul/nova-support-chat
gismatul/laravel-support-chat
networkrailbusinesssystems/oracle-api
alphabalex/messaging-made-easy
rawphp/warp
shootkiran/merobug
narakode/fineauth
numencode/wn-syncops-plugin
ibnnajjaar/mib-global-pay
refinery29/php-cs-fixer-config
parsnick/steak