CPX: The Composer Package Executor for PHP

Last updated on by

CPX: The Composer Package Executor for PHP image

The cpx CLI runs a command from any Composer package without that package being installed in your project—cpx is to Composer what npx is to npm.

If you have ever installed a tool with composer global require and then hit a dependency conflict with something else you installed globally, cpx eliminates that with isolated dependencies.

It installs each package into its own directory, separate from both your project's dependencies and your global Composer setup, then runs the command from there. Repeat runs of the same version reuse that installation, and cpx checks for updates as it goes.

Running a Package You Don't Have Installed

Pass the package name followed by the command and its arguments. A package name here is whatever you would put in your composer.json, and version constraints are supported:

cpx friendsofphp/php-cs-fixer php-cs-fixer fix ./src
cpx friendsofphp/php-cs-fixer:^3.0 php-cs-fixer fix ./src

When a package has a single binary, or its binary matches its package name, you can leave the command off:

cpx friendsofphp/php-cs-fixer fix ./src

If a package has more than one binary and you don't name one, 2.0 prompts you to pick.

You can also point cpx at a directory instead of a package name, which is useful while developing a package locally:

cpx ../my-package --version

The directory needs a valid composer.json and its dependencies installed at vendor/autoload.php. cpx runs the declared binary straight from that checkout, and does not copy, cache, or otherwise manage it.

Local Binaries Win by Default

This is the behavior change most likely to matter if you used 1.x. cpx now looks for the binary in your project before installing an isolated copy. It walks up from the current directory to find the nearest Composer project and runs the matching binary from that project's configured bin-dir:

cpx pint # runs vendor/bin/pint when the project has it
cpx phpunit --filter=Foo # runs vendor/bin/phpunit when present
cpx laravel/pint:^2.0 # uses the local pint only if it satisfies ^2.0

So inside a project, cpx pint runs the version your project pins rather than whatever is newest. When there is no matching local binary, cpx falls back to installing and running an isolated copy. To force the isolated copy, pass --skip-local before the package name.

Aliases Are Now Yours to Define

Version 1.x shipped a fixed list of shortcuts for popular packages, so cpx phpstan and cpx laravel worked out of the box. That list is gone in 2.0. You define your own instead:

cpx alias phpstan/phpstan phpstan
cpx alias laravel/pint

Leave off the alias name and it defaults to the package's short name, so the second line above creates pint. Aliases are stored in ~/.cpx/, cpx aliases lists them, and cpx unalias <name> removes one. You can alias a specific binary of a multi-binary package as well.

Two other management commands are worth knowing: cpx installed lists the packages you have run through cpx, and cpx clean removes the ones you haven't used recently (--all removes everything). Note that cpx list now shows available cpx commands, which is standard console behavior, rather than installed packages.

Running PHP Files, Gists, and a REPL

cpx exec and cpx tinker cover scratch files and quick one-offs:

cpx exec script.php
cpx exec -r 'echo PHP_VERSION;'
cpx exec https://gist.github.com/user/id
cpx tinker

Gist support downloads the file and runs it against your current directory. If the gist has several PHP files, cpx asks which one to run, or you can append the file anchor from the gist page to skip the prompt. Appending a SHA pins a revision, and setting GITHUB_TOKEN gets you past GitHub's rate limit.

Both commands do some work before your code runs. Composer's autoloader is detected in the current or a parent directory. Classes used without an import are aliased where cpx can find a match. In a Laravel project the application is fully booted, with config, facades, .env, and $app all available; in a Symfony project the kernel boots and $kernel and $container are exposed. Pass --no-boot to skip that. Your code runs in its own PHP process, so it cannot collide with cpx's bundled dependencies, and exit() codes pass through.

Inside these scripts, cpx_require() pulls in a package on demand:

cpx_require('nesbot/carbon');
 
echo Carbon\Carbon::now();

In a Laravel project with laravel/tinker installed, cpx tinker hands off to your project's own php artisan tinker and forwards arguments such as --execute. Everywhere else it opens a PsySH shell with your project booted.

Agent-Aware Output

cpx detects when it isn't attached to an interactive terminal. That covers stdin being redirected, --no-interaction or -n being passed, and running inside an AI agent, which it identifies through laravel/agent-detector.

In that mode, child processes get no TTY, prompts fall back to their defaults, and the management commands (installed, aliases, alias, unalias, clean, and update) return a single line of JSON:

{
"success": true,
"errors": [],
"summary": {
"packages": [
{ "name": "laravel/pint", "last_run": "2024-01-02 03:04:05" }
]
}
}

Package runs stream only the underlying tool's output, with cpx's own progress rendering suppressed. Failures at the cpx level, such as an unrecognized command or a package that cannot be installed, are reported as JSON too. Pass --json to get the same output from an interactive terminal. Overwriting an existing alias non-interactively requires --force.

Installing and Upgrading

cpx 2.0 requires PHP 8.3 or higher. Install it globally with Composer and make sure Composer's global bin directory is on your PATH:

composer global require cpx/cpx

Learn More

CPX was originally created by Liam Hammett. CPX 2.0 is now a first-party laravel/cpx package with multiple contributors from Laravel. If you want a live demo, Taylor Otwell introduced and demoed CPX 2.0 during his day one keynote at Laracon US 2026 in Boston.

You can read the full command reference on the laravel/cpx GitHub repository. If you are using 1.x, check out the 1.x to 2.x upgrade guide to get started with 2.x, and check out the beautiful landing page at cpx.dev.

Paul Redmond photo

Staff writer at Laravel News. Full stack web developer and author.

Filed in:
Cube

Laravel Newsletter

Join 40k+ other developers and never miss out on new tips, tutorials, and more.

image
Acquaint Softtech

Hire Laravel developers with AI expertise at $20/hr. Get started in 48 hours.

Visit Acquaint Softtech
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit: Laravel SaaS Starter Kit

SaaSykit is a Multi-tenant Laravel SaaS Starter Kit that comes with all features required to run a modern SaaS. Payments, Beautiful Checkout, Admin Panel, User dashboard, Auth, Ready Components, Stats, Blog, Docs and more.

SaaSykit: Laravel SaaS Starter Kit
Shift logo

Shift

Running an old Laravel version? Instant, automated Laravel upgrades and code modernization to keep your applications fresh.

Shift
Kirschbaum logo

Kirschbaum

Providing innovation and stability to ensure your web application succeeds.

Kirschbaum
Laravel Cloud logo

Laravel Cloud

Easily create and manage your servers and deploy your Laravel applications in seconds.

Laravel Cloud
PhpStorm logo

PhpStorm

The go-to PHP IDE with extensive out-of-the-box support for Laravel and its ecosystem.

PhpStorm
No Compromises logo

No Compromises

Joel and Aaron, the two seasoned devs from the No Compromises podcast, are now available to hire for your Laravel project. ⬧ Flat rate of $9500/mo. ⬧ No lengthy sales process. ⬧ No contracts. ⬧ 100% money back guarantee.

No Compromises
Harpoon: Next generation time tracking and invoicing logo

Harpoon: Next generation time tracking and invoicing

The next generation time-tracking and billing software that helps your agency plan and forecast a profitable future.

Harpoon: Next generation time tracking and invoicing
Lucky Media logo

Lucky Media

Get Lucky Now - the ideal choice for Laravel Development, with over a decade of experience!

Lucky Media
Acquaint Softtech logo

Acquaint Softtech

Acquaint Softtech offers AI-ready Laravel developers who onboard in 48 hours at $3000/Month with no lengthy sales process and a 100 percent money-back guarantee.

Acquaint Softtech

The latest

View all →
Laravel AI SDK Adds Human-in-the-Loop Tool Approval image

Laravel AI SDK Adds Human-in-the-Loop Tool Approval

Read article
Pest 5 Released With Test Impact Analysis, Agent Verification, and Evals image

Pest 5 Released With Test Impact Analysis, Agent Verification, and Evals

Read article
Queue-SQL: Run Mass Deletes and Updates Across Parallel Queue Jobs image

Queue-SQL: Run Mass Deletes and Updates Across Parallel Queue Jobs

Read article
Blade Formatting in Laravel Pint image

Blade Formatting in Laravel Pint

Read article
Inertia DevTools Is Now on the Chrome Web Store image

Inertia DevTools Is Now on the Chrome Web Store

Read article
Laravel LSP: A First-Party Language Server Announced at Laracon US 2026 image

Laravel LSP: A First-Party Language Server Announced at Laracon US 2026

Read article