Composer Scripts and Custom Tools in PhpStorm: Casting Buttons
AI generated
IDE
{ }
PhpStorm · Composer · External Tools · PHP Tooling
Composer Scripts and Custom Tools in PhpStorm
as Buttons, Step by Step

Anyone who keeps typing phpcs, phpstan or bin/magento cache:flush into the terminal loses time and focus. PhpStorm lets you integrate any Composer script, any shell command and any Docker wrapper script as a button directly in the IDE: clickable, with output in the Run window and optionally triggerable with a keyboard shortcut.

12 min read Composer Scripts · External Tools · Run Configurations · Toolbar PhpStorm 2024.x · PHP 8.x · Magento 2

1. Why buttons instead of the terminal: the actual payoff

Switching between IDE and terminal costs more than the pure typing time. Every time a developer switches to the terminal, types a command and waits for the result, the development flow is interrupted. Worse still: if the command is run in a new terminal window, context is lost, which file was open, which line was highlighted? PhpStorm solves this problem by integrating tools directly into the IDE.

The output of External Tools and Composer Scripts appears in the PhpStorm Run window, which is directly linked to the editor. Error output is parsed, and when the tool outputs file names and line numbers, like phpcs or phpstan do, they are directly clickable. Clicking the error message opens the affected file at the exact position. This is not a time saving of seconds, but a qualitative improvement of the development process. Buttons and shortcuts can also be stored in `.idea/` files and shared across the team, so everyone uses the same workflow.

2. Composer Scripts: what they can do and where their limits lie

Composer Scripts are shell commands or PHP callbacks defined in composer.json under the scripts key and executed via composer run-script scriptname. They are excellent for project-specific tools that are already managed through Composer anyway: phpcs, phpstan, phpunit, php-cs-fixer. The advantage is that every developer who runs composer install automatically has the same scripts available, no separate documentation, no manual setup.

Composer Scripts do have limits, though: they always run in the directory where composer.json is located and cannot automatically receive context information from the IDE, such as the currently open file, as a parameter. For use as an IDE button that reacts to the current file, you need External Tools. Composer Scripts also lack the ability to dynamically pass environment variables or file parameters. For simple project-wide analysis runs, however, they are ideal and considerably leaner than a full Run Configuration.


{
  "require-dev": {
    "squizlabs/php_codesniffer": "^3.9",
    "phpstan/phpstan": "^1.11",
    "phpstan/phpstan-strict-rules": "^1.6"
  },
  "scripts": {
    "cs": "phpcs --standard=PSR12 src/app/code/",
    "cs-fix": "phpcbf --standard=PSR12 src/app/code/",
    "analyse": "phpstan analyse --level=8 --memory-limit=512M src/app/code/",
    "test": "phpunit --configuration phpunit.xml",
    "check": [
      "@cs",
      "@analyse"
    ],
    "post-install-cmd": [
      "@composer dump-autoload --optimize"
    ]
  },
  "scripts-descriptions": {
    "cs": "Run PHP_CodeSniffer against app/code",
    "cs-fix": "Auto-fix code style violations",
    "analyse": "Run PHPStan static analysis at level 8",
    "check": "Run all quality checks in sequence"
  }
}

3. Running Composer Scripts directly in PhpStorm

PhpStorm automatically detects Composer Scripts when a composer.json is present at the project root. In the Composer window (View → Tool Windows → Composer), all defined scripts are listed. Double-clicking a script name runs it, and the output appears in the Run window at the bottom. That already covers the first step of integration, without any further configuration.

To pin a Composer Script as a permanent button in the toolbar, first create a Run Configuration of type Composer Script: Run → Edit Configurations → + → Composer Script. There you select the script name from the dropdown and, if needed, provide additional arguments. This Run Configuration can then be pinned via the button next to the toolbar's dropdown list. The next time the IDE starts, the button is immediately available. For the team, it is a good idea to mark the Run Configuration as Shared, so it gets written to the .idea/ directory and checked into the Git repository.

4. External Tools: the most flexible tool in PhpStorm

External Tools in PhpStorm (Settings → Tools → External Tools) allow you to run any command-line program with dynamic parameters from the IDE context. The strength lies in the macros: $FilePath$ returns the absolute path of the currently open file, $FileDir$ the directory, $ProjectFileDir$ the project root, $LineNumber$ the current line number. This lets you run phpcs exactly for the active file, not for the entire directory.

An External Tool consists of three required fields: Program (the path to the program), Arguments (command-line arguments with macros) and Working directory (usually $ProjectFileDir$). Optionally, the tool can be assigned to a group, which makes organization easier once you have set up many tools. The output appears in the Run window, and if Open console for tool output is enabled, focus jumps there automatically. If PhpStorm recognizes the output as an error format, for example the pattern file.php:42, the line in the output becomes clickable.


<!-- External Tool: phpcs for current file -->
<!--
  Name: phpcs (Current File)
  Group: PHP Quality
  Program: $ProjectFileDir$/vendor/bin/phpcs
  Arguments: --standard=PSR12 --report=emacs $FilePath$
  Working directory: $ProjectFileDir$
-->

<!-- External Tool: phpstan for current file -->
<!--
  Name: phpstan (Current File)
  Group: PHP Quality
  Program: $ProjectFileDir$/vendor/bin/phpstan
  Arguments: analyse --level=8 --memory-limit=256M $FilePath$
  Working directory: $ProjectFileDir$
-->

<!-- External Tool: php-cs-fixer for current file -->
<!--
  Name: cs-fixer (Fix Current File)
  Group: PHP Quality
  Program: $ProjectFileDir$/vendor/bin/php-cs-fixer
  Arguments: fix $FilePath$ --rules=@PSR12
  Working directory: $ProjectFileDir$
-->

<!-- External Tool: Magento cache:flush -->
<!--
  Name: Magento cache:flush
  Group: Magento
  Program: $ProjectFileDir$/bin/magento
  Arguments: cache:flush
  Working directory: $ProjectFileDir$
-->

5. Setting up Docker wrapper scripts as External Tools

In Docker-based development environments, like the Mark Shust setup for Magento 2, PHP, phpcs and every other tool run inside the container. No PHP is installed on the host system. That means you cannot call vendor/bin/phpcs directly, but must always use the wrapper bin/phpcs, which runs the command via docker exec inside the running container.

Setting up such wrappers as an External Tool in PhpStorm is straightforward: in the Program field you enter the absolute or relative path to the wrapper script, for example $ProjectFileDir$/bin/phpcs. The Arguments field then contains the arguments the wrapper passes on to the container. Important: the working directory must point to $ProjectFileDir$, so the wrapper script can correctly identify the container. A common mistake is entering the program as an absolute system path, which bypasses the wrapper logic. Always test the External Tool first via Tools → External Tools → run the tool name, before adding it to the toolbar.

6. Integrating buttons into the toolbar

PhpStorm allows you to fully customize the toolbar. Via View → Appearance → Toolbar you can show the main toolbar. For the actual customization, navigate to Settings → Appearance & Behavior → Menus and Toolbars → Main Toolbar → Toolbar Run Actions. There you can add new actions with the plus icon. External Tools appear under External Tools → Group → Tool Name, Run Configurations under Run Configurations. A meaningful icon makes identification easier: PhpStorm lets you pick from the built-in icon set.

A good toolbar strategy for PHP projects: frequently used actions like "phpcs fix current file" and "analyse current file" go on the left, project-wide actions like "full analysis" and "cache:flush" further to the right. Separators between groups help with visual orientation. If the team is meant to share the same toolbar, it is enough to save the Run Configurations as Shared, the toolbar configuration itself lives in .idea/workspace.xml and is user-specific, but the underlying actions are shareable.

7. Assigning keyboard shortcuts to External Tools

Buttons in the toolbar are convenient, keyboard shortcuts are faster. PhpStorm lets you assign a dedicated keyboard shortcut to every External Tool. This works via Settings → Keymap → External Tools → Group → Tool Name → Right-click → Add Keyboard Shortcut. As a convention, a prefix such as Alt+Q followed by a unique letter is recommended: Alt+Q, C for phpcs, Alt+Q, A for phpstan, Alt+Q, F for cs-fixer. Such chord shortcuts are rarely occupied by existing bindings and easy to remember.

For Magento-specific commands, direct single shortcuts are a good option, as long as they are not already taken. Shift+F10 is occupied by Run, but Ctrl+Shift+F10 is free in many keymaps. Important: keymaps are stored per user in ~/.config/JetBrains/PhpStorm*/keymaps/ and are not automatically picked up by the repository. Document the recommended shortcuts in the project's CLAUDE.md or README so all developers use the same bindings.


<?php
// PhpStorm External Tool Output Format Examples
// Configure "Output Filters" to make paths clickable

// phpcs emacs format, PhpStorm recognizes this automatically:
// /path/to/file.php:42:1: error - Expected 1 space after IF keyword; 0 found (Squiz.ControlStructures.ControlSignature)

// phpstan output, also recognized automatically:
//  12     Parameter $id of method Mironsoft\Catalog\Model\Product::load()
//         expects int, string given.

// Custom output filter regex for PhpStorm:
// Pattern: $FILE_PATH$\:$LINE$
// Applied to tool output to make lines clickable

// Macro variables available in External Tools:
// $FilePath$        - absolute path to currently open file
// $FileDir$         - directory of currently open file
// $FileName$        - filename without path
// $FileExt$         - file extension without dot
// $ProjectFileDir$  - project root directory
// $LineNumber$      - cursor line in currently open file
// $SelectedText$    - currently selected text in editor
// $Clipboard$       - current clipboard contents

8. Run Configurations for more complex workflows

When a single tool is not enough and several steps need to run in sequence, Run Configurations are the right choice. They support Before launch actions: you can, for instance, create a Run Configuration that first runs the CSS build, then deploys static content and finally flushes the cache, all with a single click. The Shell Script type in Run Configurations is the most flexible option for this, since it supports arbitrary shell commands and pipes.

For Magento 2 projects with a Docker wrapper, a combination is recommended: the Before-launch action calls bin/npm --prefix ... run build (as an External Tool), while the actual Run Configuration then runs bin/magento setup:static-content:deploy and bin/magento cache:flush. That gives you a "Deploy" Run Configuration that maps the entire deploy cycle into a single step. If something goes wrong, the error is visible in the Run window and the step is identifiable, considerably more pleasant than manually typing out a four-step deploy sequence.

9. Composer Scripts vs. External Tools vs. Run Configurations

The three integration types in PhpStorm complement each other but also overlap. The right choice depends on the use case.

Criterion Composer Scripts External Tools Run Configurations
IDE context No Yes ($FilePath$, $LineNumber$) Limited
Team-friendly (Git) Yes (composer.json) Manual (share .idea/) Yes (mark as Shared)
Multi-step Yes (arrays in scripts) No (single tool) Yes (Before launch)
Toolbar button Possible via Run Config Direct Direct
Docker wrapper Only if in composer.json Yes, fully Yes, via Shell Script

The recommendation for Magento 2 projects with Docker: Composer Scripts for quality-assurance tools (phpcs, phpstan) that every developer should know locally. External Tools for file- or line-related actions like "fix current file". Run Configurations for multi-step workflows like deploy sequences. All three types can coexist in parallel and complement each other well.

Mironsoft

PhpStorm setup, PHP tooling and Magento 2 development

Want your development environment optimized?

We set up PhpStorm for Magento 2 Docker projects end to end, with Composer Scripts, External Tools, Docker interpreter and deploy workflows as toolbar buttons.

IDE setup

Fully configure PhpStorm for Docker-based Magento 2

Tooling integration

phpcs, phpstan, cs-fixer as toolbar buttons and keyboard shortcuts

Team templates

Shared Run Configurations and keymaps for a consistent team workflow

10. Summary

Composer Scripts, External Tools and Run Configurations in PhpStorm solve the problem of development being interrupted by switching to the terminal. Composer Scripts define project-wide quality tools directly in composer.json and are available to every team member after a composer install. External Tools integrate any command-line program with IDE context such as $FilePath$ and make phpcs or phpstan output directly clickable. Run Configurations enable multi-step workflows with Before-launch actions.

For Docker-based Magento 2 projects, the key is to enter the existing wrapper scripts from the bin/ directory as the Program in External Tools. That way PhpStorm uses the same wrappers that are also used manually in the terminal, without double configuration. Toolbar buttons and keymap shortcuts round out the setup and turn quality assurance into a natural part of the development flow instead of a tedious mandatory step after coding.

PhpStorm Custom Tools: The Essentials at a Glance

Composer Scripts

Define in composer.json under scripts, automatically visible in PhpStorm, shareable team-wide via Git, ideal for project-wide quality analyses.

External Tools

Settings → Tools → External Tools, with $FilePath$ and $LineNumber$ for file-based actions. Output in the Run window, errors clickable.

Toolbar buttons

Settings → Appearance & Behavior → Menus and Toolbars, add External Tools and Run Configurations directly as a button.

Docker wrapper

Enter wrapper scripts from bin/ as Program in External Tools, no PHP installation on the host needed, everything runs in the container.

11. FAQ: Composer Scripts and Custom Tools in PhpStorm

1Add a Composer Script as a toolbar button?
Create a Run Configuration of type "Composer Script", then add it via Settings → Menus and Toolbars. Mark as Shared for team sharing via .idea/.
2External Tools vs. Run Configurations?
External Tools for individual programs with $FilePath$ context. Run Configurations for multi-step workflows with Before-launch actions and team sharing.
3Docker wrapper as an External Tool?
Enter the path to the wrapper in the Program field: $ProjectFileDir$/bin/phpcs. Working directory: $ProjectFileDir$. The wrapper forwards docker exec to the container.
4Sharing External Tools with the team?
The file in ~/.config/JetBrains/PhpStorm*/tools/ lives outside the repo. As an alternative, save the actions as a Run Configuration (Shell Script, Shared) in .idea/ for automatic sharing.
5Assign a keyboard shortcut to an External Tool?
Settings → Keymap → External Tools → Right-click → Add Keyboard Shortcut. Chord shortcuts like Alt+Q, C are recommended, rarely taken, easy to remember.
6Make phpcs output clickable?
Call phpcs with --report=emacs. The format file.php:42:1: error - ... is automatically recognized by PhpStorm as a clickable path.
7Limit a Composer Script to the current file?
Composer Scripts have no IDE context. For file-based actions, use External Tools with $FilePath$ as an argument.
8Several Magento commands as one Run Config?
Create a Run Configuration of type Shell Script, chain commands with &&. Use Before-launch for preceding steps such as a CSS build.
9Prevent a new console window on every tool call?
Disable "Open console for tool output" in External Tool Settings. Output then lands in the existing Run tab, no window switch.
10Run Configurations automatically into the Git repo?
Only with the "Store as project file" (Shared) option enabled. Then the XML lands in .idea/runConfigurations/, automatically checked in and available to everyone.