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 Installers Laravel Package

cartalyst/composer-installers

A Composer installer plugin that registers custom install paths for Cartalyst packages, placing extensions in their expected directories. Mainly relevant to legacy Cartalyst projects; modern setups rarely need it.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Composer plugin, not a runtime Laravel package. It has no service provider, no config file you publish, and nothing to register in config/app.php. "Getting started" means getting Composer to load it and confirming it actually relocates Cartalyst packages during install.

1. Require it in the project that consumes Cartalyst packages.

composer require cartalyst/composer-installers:^1.2

Pin to ^1.2 (or the exact 1.2.1) — the last release is September 2014, and there will never be a 1.3. If you cannot reach Packagist for the tag, mirror it into a path or vcs repository:

"repositories": [
  { "type": "path", "url": "../vendor-src/composer-installers" }
]

2. Confirm Composer actually activated it.

The plugin only does anything if Composer loads it as a plugin. Check with:

composer show cartalyst/composer-installers
composer install -vvv 2>&1 | grep -i cartalyst

If you see no plugin activation line, the installer is inert and any Cartalyst packages will land in vendor/ — which most people misdiagnose as a "wrong path" bug.

3. Look at the installer source first, not the docs.

There is essentially no documentation. The mapping lives in code — open the plugin's installer classes and read supports() and getInstallPath(). Those two methods are the configuration. Note the directory that contains the "paths file" referenced in the v1.2.1 changelog ("Use default paths if the paths file does not exist") — that file, when present, is how you override the baked-in paths without forking.

4. First real use case.

The canonical scenario: a legacy Cartalyst Platform application declares a Cartalyst extension package whose type is a Cartalyst package type (cartalyst-platform, extension types, theme types — confirm the exact strings from supports()). Without the plugin, Composer drops the package in vendor/ and the platform cannot find it. With the plugin active, composer require / composer update places it in the app-relative directory the platform expects (e.g. extensions/, themes/, platform/). After install, verify the filesystem:

composer install -vvv
find . -maxdepth 3 -type d -name 'vendor' -prune -o -type d -print | grep -iE 'extension|theme|platform'

Implementation Patterns

Per-project pin, not a global install

Do not composer global require this. The plugin is project-scoped by design — the install paths it computes are relative to the application root. Add it to each affected composer.json with an exact pin:

"require": {
    "cartalyst/composer-installers": "1.2.1"
}

Use an exact version, not ^1.2. You are not going to get a patch, and an exact pin keeps lockfile diffs boring.

Keep it in require, and verify that on the deploy target

If it lives in require-dev, a production build with composer install --no-dev will not load the plugin, and packages will be installed into vendor/ instead of their platform paths. That divergence between CI and production is the single most common failure with this package. Put it in require, and validate after deploy:

composer show cartalyst/composer-installers   # run on the deploy host, not just CI

Override install paths via the paths file

Because getInstallPath() derives paths from a "paths file" (falling back to defaults if absent, per v1.2.1), the supported extension point is that file — not a service provider, not a config publish. If your app layout deviates from the Cartalyst defaults (custom app/ root, multi-tenant directory per site, etc.), create the paths file at the location the installer looks for and override there. Read the installer source to confirm the exact filename/relative location before creating it, then commit it alongside composer.json.

Local development: path repositories for Cartalyst packages

When you are actively editing a Cartalyst extension, use a path repository with a symlink so the plugin's install path stays live:

"repositories": [
  { "type": "path", "url": "packages/my-cartalyst-extension", "options": { "symlink": true } }
],
"minimum-stability": "dev",
"prefer-stable": true

The installer will still resolve getInstallPath() for the package type, so you get a symlink at extensions/… pointing into your working copy. Confirm with ls -l, not just composer show.

Isolate Composer version behavior in CI

If any of your pipelines still run Composer 1 while developers are on Composer 2, you have two different plugin activation models. Split the pipeline step:

- name: Install
  run: |
    composer --version
    composer install --no-interaction -vvv
    test -d extensions || (echo "installer did not relocate packages" && exit 1)

That test -d is a cheap day-to-day guard against silent non-activation.

Wrap it in a migration ticket, not a dependency list entry

Practically, "leveraging" this package day-to-day means using it while you remove the Cartalyst packages that need it. Grep the codebase for the install-path directories (extensions/, themes/, platform/) and confirm whether anything at runtime assumes those paths, then replace with PSR-4 autoloading and php artisan vendor:publish where possible.

Gotchas and Tips

Composer 2 will not just work. A 2014-era plugin predates Composer 2's plugin API and the allow-plugins allowlist. Expect one of: install refused, plugin silently not activated, or a hard class-not-found in the plugin. If you must run it under Composer 2, add the allowlist entry explicitly and test in a throwaway branch first:

"config": {
  "allow-plugins": {
    "cartalyst/composer-installers": true
  }
}

If allow-plugins is set and the package is missing from it, Composer 2 will not activate the plugin — and the failure mode is packages in vendor/, not an error mentioning the plugin. That is the trap.

--no-plugins silently disables everything. Any Dockerfile, CI step, or host deploy hook that passes --no-plugins (often to bypass a different plugin) turns this package off. Search every build script for that flag before debugging paths.

composer.lock will mislead you. The lockfile records the package type but not the resolved install path. Two installs of the same lockfile can produce different trees depending on whether the plugin loaded and whether the paths file exists. Always verify against the filesystem or composer install -vvv, never against the lockfile.

v1.2.1's "default paths when the file is missing" is a footgun, not a feature. If someone deletes or renames the paths file, the plugin quietly falls back to defaults instead of erroring. You get a working install in the wrong directory. Treat the paths file as source-of-truth infrastructure and commit it; add a CI check that it exists if you rely on overrides.

Plugin ordering matters. Do not introduce this alongside composer/installers, oomphinc/composer-installers-extender, or other path-mutating plugins without testing. Two plugins both claiming supports() for a package type leads to whichever registers first winning, and "it worked yesterday" is the usual symptom.

No autoload awareness. The installer moves files; it does not add the moved directory to the autoloader. If a relocated Cartalyst package relied on Composer's PSR-4 autoload from vendor/, you must ensure the application's own autoload block covers the new location, or the package will be found on disk but fail with class-not-found at runtime. This is a path bug on the surface and an autoload bug underneath.

Licensing is a gate, not a footnote. The license is NOASSERTION. For internal or legacy use that's a review item; for redistribution or a commercial product it is a blocker until clarified. Record it in the dependency register on day one and get a named owner for the sign-off.

There is no upstream. Zero stars, zero dependents, no release in a decade, no CVE coverage. If it breaks, you read getInstallPath() and patch the vendored copy yourself. Budget for that — vendoring the source into the repo (or a path repository) is cheaper than discovering mid-incident that Packagist is the only copy.

Debugging checklist when paths look wrong, in order:

  1. composer show cartalyst/composer-installers (installed at all?)
  2. Composer version and --no-plugins in the build script
  3. allow-plugins entry present under Composer 2
  4. Paths file present and committed, or defaults intentionally used
  5. composer install -vvv output for plugin activation and install path lines
  6. ls -l on the target directory (symlink vs real dir for path repos)
  7. require vs require-dev and --no-dev on the deploy target

The best long-term "tip" is deletion. The replacement sequence is: replace dependent Cartalyst packages with standard-autoloading equivalents, confirm nothing still declares a Cartalyst package type, then remove this plugin and regenerate the lockfile. composer/installers with a custom type or oomphinc/composer-installers-extender are viable interim shims if you must preserve the path contract while retiring the abandoned dependency.

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