Automate your PHP and Laravel workflow with custom Composer scripts


Most PHP/Laravel developers use Composer only for dependency management, but few take advantage of Composer custom scripts. Scripts allow you to automate repetitive tasks like testing, static code analysis, refactoring or initial project setup, simplifying the workflow and reducing errors. Laravel itself defines a few, to simplify the configuration of the project or the execution of certain tasks.

What is a Composer script

Inside the scripts section of a composer.json file you can define custom scripts. For example:

{
  "scripts": {
    "test": "XDEBUG_MODE=off ./vendor/bin/pest --parallel"
  }
}

After defining the test script, if you run it from the shell

composer test

you will see that project tests (unit, feature, etc.) will run, in this case using Pest, in parallel and disabling XDebug (which in my local environment is always active — vice versa, you might want to keep it always disabled and enable it only when needed).

Why use Composer scripts?

There are many benefits:

  • ✅ consistency: all team members use the same commands
  • ⚙️ automation: no more long, forgotten, or incorrectly parameterized commands
  • 🧩 CI/CD integration: scripts easily integrate into GitHub Actions, GitLab CI, etc. pipelines
  • 💡 project cleanliness: avoid adding duplicate shell files to the repository and keep configuration in the composer.json file

Practical tips

  • for script names, don’t use names of libraries, products or technologies, but terms that represent the task you want to perform. The reason is simple: if today you use a library to execute that task, tomorrow you might replace it with another one that performs the same task (perhaps better); in that case, you would have to change also the script name.

    Example:

    ❌ `composer phpunit`
    ❌ `composer pest`
    ✅ `composer test`

    Another example:

    ❌ `composer rector`
    ✅ `composer refactor`
  • use the same script names in all PHP/Laravel projects, so you can find them everywhere and use them easily and with familiarity

  • if a project doesn’t use PHPStan or Rector, for example, don’t add the corresponding scripts to the composer.json file: making them available might confuse other developers

  • if you have XDebug active, use XDEBUG_MODE=off at the beginning of the command to disable it and speed up execution (for example of the test suite or static analysis)

Practical examples of useful scripts

Static code analysis

  • analyse
"analyse": "XDEBUG_MODE=off ./vendor/bin/phpstan analyse --memory-limit 2G --ansi"

Performs static code analysis with PHPStan.

  • analyse-clear-cache
"analyse-clear-cache": "./vendor/bin/phpstan clear-result-cache"

Clears PHPStan cache (sometimes necessary in case of static analysis issues).

Code refactoring

  • refactor
"refactor": "XDEBUG_MODE=off rector process --ansi"

Performs code refactoring via Rector.

  • refactor-dry
"refactor-dry": "XDEBUG_MODE=off rector --dry-run --ansi"

Runs Rector in dry run mode, without modifying files: shows only what changes will be made.

Code formatting

  • format
"format": "vendor/bin/pint --dirty --parallel --ansi"

Performs code formatting with Pint only on modified files and in parallel.

Tests and code coverage

  • test
"test": "XDEBUG_MODE=off ./vendor/bin/pest --parallel --bail --colors=always"

Runs tests with Pest. Tests are run in parallel, and if one fails, the execution is stopped.

  • test-architecture
"test-architecture": "XDEBUG_MODE=off ./vendor/bin/pest --parallel --bail --group=architectural --colors=always"

Runs only architecture tests with Pest.

  • test-coverage
"test-coverage": "php -d memory_limit=-1 ./vendor/bin/pest --coverage --min=80"

Runs tests with code coverage and shows the report. If the coverage is lower than 80%, the command fails.

  • type-coverage
"type-coverage": "XDEBUG_MODE=off ./vendor/bin/pest --type-coverage"

Runs type coverage with Pest to report in which files you can add type to parameters and return types.

Conclusion

Composer scripts are a simple but powerful way to standardize and speed up development in PHP and Laravel. Start by defining a few key commands, and you’ll immediately see the difference in your daily workflow.

They will also help other developers on your team and provide a standardized method for executing the necessary tasks.

The ones listed above are the ones I use most frequently; define them based on your needs and those of your team.