Indexing, Excludes, Performance & Autocomplete
With over 30,000 PHP files, Magento 2 is one of the largest open-source PHP projects. Without a correct PhpStorm configuration, indexing takes minutes, autocomplete stays silent, and the IDE turns into a bottleneck instead of a helper. This guide shows how to set up PhpStorm so it works productively with Magento.
Table of Contents
- 1. The Core Problem: Magento 2 Overwhelms Unconfigured IDEs
- 2. Indexing Excludes: What PhpStorm Should Not Index
- 3. Setting Up the PHP Interpreter Correctly (Local and Docker)
- 4. DI Autocomplete: Resolving Interfaces and Virtual Types
- 5. Plugin Autocomplete and Interceptor Navigation
- 6. Memory Limits and IDE Performance Tuning
- 7. Code Style Configuration for Magento Coding Standards
- 8. Path Mappings for Docker Deployments
- 9. Configuration With and Without Optimization Compared
- 10. Summary
- 11. FAQ
1. The Core Problem: Magento 2 Overwhelms Unconfigured IDEs
Anyone who points PhpStorm at a fresh Magento 2 project without any adjustments experiences the same thing: the IDE starts indexing and seemingly never stops. The reason lies in the sheer number of files. A standard Magento 2 installation with Composer dependencies, generated factories, interceptors and frontend assets easily exceeds 500,000 files, and by default PhpStorm tries to index all of them. That costs memory, CPU time, and measurably slows down every search, code navigation and completion request.
The real problem is not Magento itself, but the ratio of relevant to irrelevant code. The generated files in generated/, compiled assets in pub/static/, the Composer cache in var/cache/ and frontend node modules are all irrelevant to PHP development. PhpStorm does not need them to provide autocomplete and navigation. Configured correctly, PhpStorm stays responsive even with Magento 2, and the autocomplete difference is noticeable: instead of generic type hints, you see concrete classes, interfaces and even generated factories.
2. Indexing Excludes: What PhpStorm Should Not Index
The first and most important step is setting up excluded directories. In the project settings (File → Settings → Directories), you mark directories as Excluded. PhpStorm skips these entirely during indexing, search and autocomplete requests. For Magento 2, the following directories should be marked as excluded: generated/, pub/static/, var/, dev/tests/ (unless you are actively working on tests), setup/ and update/. Node modules in frontend themes (node_modules/) as well.
One important nuance: generated/code/ contains the generated factories, proxies and interceptors. This is PHP code that PhpStorm could theoretically use for autocomplete, but it creates more noise than benefit. If you want DI autocomplete, it is better solved through the magento-phpstorm-plugin (more on that later), not by indexing generated files. Magento's plugin delivers type information directly from the XML configuration files, which is more precise and easier to maintain.
// .idea/mironsoft.iml (Mark directories in PhpStorm Project Structure)
// Settings → Directories → Mark as Excluded
// EXCLUDE these directories completely:
// generated/ ← generated factories, interceptors, proxies
// pub/static/ ← compiled CSS/JS, no PHP relevance
// var/ ← cache, session, log, compiled templates
// dev/tests/ ← only include when writing integration tests
// setup/ ← Magento install scripts, rarely touched
// node_modules/ ← frontend packages under any theme
// KEEP indexed (Sources Root):
// app/code/ ← custom modules
// app/design/ ← theme templates and layouts
// vendor/magento/ ← core modules for navigation
// vendor/ ← all Composer dependencies
After setting the excludes, it is worth manually invalidating the PhpStorm index once (File → Invalidate Caches) and restarting the IDE. The initial indexing after this action takes significantly less time than before, and the IDE stays responsive afterward because the index is much smaller. On modern machines with an SSD, a full re-index after excludes is usually done in under two minutes, whereas without excludes the same project can take ten minutes or more.
3. Setting Up the PHP Interpreter Correctly (Local and Docker)
Without a correctly configured PHP interpreter, PhpStorm cannot run code quality analyses, PHPStan or real-time inspections. Under Settings → PHP → CLI Interpreter, you either enter the local PHP binary path or, with a Docker setup such as the Mark Shust setup, a Docker interpreter. For Docker, you choose From Docker, Vagrant, VM... and connect PhpStorm to the PHP container. Important: pick the correct PHP container, not the Nginx or MariaDB container.
For the Mark Shust Docker setup, this specifically means selecting the phpfpm service or the appropriate PHP container name from compose.yaml. PhpStorm automatically reads the PHP version from the container and detects installed extensions. This matters because Magento 2.4.x requires specific extensions such as ext-intl, ext-soap and ext-gd, and PhpStorm needs to know about them for correct code analysis. A misconfigured interpreter causes the IDE to flag extension calls as errors even though they run correctly inside the container.
4. DI Autocomplete: Resolving Interfaces and Virtual Types
Magento's dependency injection system separates interface from implementation via di.xml. When a controller receives ProductRepositoryInterface in its constructor, PhpStorm has no way of knowing which concrete class is behind it without additional information, and so it only offers the interface's methods, not those of the implementation. The Magento PHPStorm Plugin (available on the JetBrains Marketplace) solves this problem by evaluating di.xml preferences and virtual types and feeding PhpStorm the corresponding type mappings.
After installing the plugin, a configuration section appears under Settings → PHP → Frameworks → Magento. There you enter the Magento root path and enable framework support. From that point on, PhpStorm navigates from an interface type in the constructor directly to the configured implementation, including Ctrl+Click navigation. Factories like ProductFactory are also resolved correctly, even when the class only exists as a generated file and is not part of the source code.
<?php
declare(strict_types=1);
namespace Mironsoft\Catalog\Model;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\ProductFactory;
use Magento\Framework\App\Config\ScopeConfigInterface;
/**
* Product service demonstrating DI autocomplete in PhpStorm.
* With the Magento PHPStorm Plugin installed, PhpStorm resolves:
* - ProductRepositoryInterface → Magento\Catalog\Model\ProductRepository
* - ProductFactory → generated/code/Magento/Catalog/Model/ProductFactory.php
* - ScopeConfigInterface → Magento\Framework\App\Config
*/
class ProductService
{
public function __construct(
private readonly ProductRepositoryInterface $productRepository,
private readonly ProductFactory $productFactory,
private readonly ScopeConfigInterface $scopeConfig,
) {}
/**
* Load product by SKU with full autocomplete on return type.
*/
public function getBySku(string $sku): \Magento\Catalog\Api\Data\ProductInterface
{
// PhpStorm knows the exact return type, so navigation works
return $this->productRepository->get($sku);
}
}
5. Plugin Autocomplete and Interceptor Navigation
Magento's plugin system (interceptors) is one of the areas where PhpStorm is blind without specific support. A plugin defines before, after or around methods for methods of another class. The connection between plugin and target class is only defined in di.xml, and PhpStorm cannot find it without help. The Magento PHPStorm Plugin shows icons in the gutter (the left margin of the editor) that navigate directly from a method to all its assigned plugins, and vice versa.
When developing your own plugins, it is important to know the correct method signatures. A beforeMethod plugin receives the subject (the target class) as its first parameter, followed by the original method parameters. An aroundMethod plugin additionally receives a callable $proceed. With the plugin enabled, PhpStorm generates these signatures correctly via code completion as you type the method name. Without the plugin, you have to look up the signatures manually, which is a real productivity loss when developing plugins frequently.
6. Memory Limits and IDE Performance Tuning
PhpStorm runs on the JVM and needs sufficient heap memory for large projects like Magento. The default value of 750 MB is not enough for Magento 2. 2 GB is a reasonable starting point, and 4 GB is recommended for development machines with 16+ GB RAM. The setting is found under Help → Edit Custom VM Options: -Xmx4096m sets the maximum to 4 GB. After restarting the IDE, you immediately notice the difference in the response speed of autocomplete and search.
It is also worth limiting the number of background indexing threads under Settings → Appearance & Behavior → System Settings. On development machines with parallel Docker containers, aggressive background indexing can load the CPU heavily enough that other processes suffer. Another optimization: put PhpStorm's system temp folder on an SSD, or explicitly configure it via idea.system.path, so the index cache sits on the fastest drive.
7. Code Style Configuration for Magento Coding Standards
Magento 2 largely follows the PSR-12 standard with a few extensions. PhpStorm can be configured to format automatically and show code style violations as warnings. Under Settings → Editor → Code Style → PHP, you import a prebuilt scheme or adjust manually: 4 spaces indentation, no tabs, LF line endings, maximum line length of 120 characters. The most important setting for Magento development: Blank lines → Around class body set to 1, and Method/Function Body aligned with Magento's conventions.
For automatic formatting on save, enable Settings → Tools → Actions on Save → Reformat Code. That ensures no commit with incorrectly formatted code ever makes it into the repository. Combined with phpcs and the Magento Coding Standard ruleset, PhpStorm can additionally display violations directly in the editor: under Settings → PHP → Quality Tools → PHP_CodeSniffer, enter the path to the phpcs binary and the Magento2 ruleset. From that point on, coding standard violations appear as yellow or red underlines directly in the code.
8. Path Mappings for Docker Deployments
When working with Docker setups (such as the Mark Shust setup), files live at a different path on the local machine than inside the container. PhpStorm needs to know about this discrepancy in order to correctly associate Xdebug sessions. Without path mappings, PhpStorm reports that it cannot find the file when hitting an Xdebug breakpoint, because the container path /var/www/html/ does not match the local project path. Path mappings are configured under Settings → PHP → Servers.
For the Mark Shust setup, this means creating a server named mironsoft.de, entering host and port, and mapping the local path /home/mir/development/mironsoft/src to the container path /var/www/html under Path Mappings. This allows PhpStorm to set Xdebug breakpoints correctly, resolve stack traces, and fully use remote debugging sessions. The same path mappings are also needed for remote PHPUnit configurations and for running phpcs inside the container.
<?php
// PhpStorm Path Mapping example for Mark Shust Docker setup
// Settings → PHP → Servers → mironsoft.de
// Local path: /home/mir/development/mironsoft/src
// Container path: /var/www/html
// .env configuration for Xdebug in Docker:
// XDEBUG_MODE=debug
// XDEBUG_CONFIG="client_host=host.docker.internal client_port=9003"
// XDEBUG_SESSION=PHPSTORM
// In PhpStorm: Settings → PHP → Debug
// Debug Port: 9003
// Server name: mironsoft.de (must match PHP_IDE_CONFIG server name)
// bin/xdebug enable ← Mark Shust wrapper to toggle Xdebug
// After enabling: restart fpm container, PhpStorm listens on 9003
// Verify mapping works:
// 1. Set breakpoint in Magento\Framework\App\Http::launch()
// 2. Open browser with ?XDEBUG_SESSION=1
// 3. PhpStorm should pause at breakpoint with full variable inspection
9. Configuration With and Without Optimization Compared
The difference between an unconfigured and an optimized PhpStorm setup for Magento 2 is clearly noticeable in day-to-day work. The following table summarizes the most important differences and shows which settings have the biggest effect.
| Area | Without Optimization | With Optimization | Setting |
|---|---|---|---|
| Initial indexing | 8 to 15 minutes | 1 to 2 minutes | Excludes: generated/, pub/, var/ |
| DI autocomplete | Interface methods only | Concrete class + navigation | Magento PHPStorm Plugin |
| Xdebug remote | File not found | Breakpoints work | Path Mappings configured |
| IDE response time | Noticeable delays | Smooth and instant | -Xmx4096m in VM Options |
| Code style checks | Manual via CLI | Visible inline in the editor | phpcs + Magento2 ruleset |
The numbers in the table are not theoretical, they come from actually setting up PhpStorm on Magento 2 projects. The biggest single gain comes from the excludes: excluding the generated directories and the var/ folder from the index halves or thirds the indexing time and noticeably improves autocomplete speed. The Magento PHPStorm Plugin is the second big step, because it enables the DI resolution that Magento otherwise fundamentally obscures without plugin support.
Mironsoft
Magento 2 development, PhpStorm setups and developer tooling
Want PhpStorm to be productive for Magento?
We set up PhpStorm for your Magento 2 project, with correct excludes, DI autocomplete, Xdebug integration and code style automation for your entire development team.
IDE Audit
Analyze existing PhpStorm configurations and identify optimization potential
Team Setup
Unified IDE configuration for entire development teams, committed to the repository
Tooling Integration
Integrate PHPStan, phpcs and Xdebug directly into PhpStorm and roll them out to the team
10. Summary
A well-configured PhpStorm installation for Magento 2 differs from a standard installation in three main areas: indexing excludes, DI autocomplete and path mappings. The excludes for generated/, pub/static/ and var/ drastically reduce the amount of indexed files and keep the index current and precise. The Magento PHPStorm Plugin resolves the DI connection between interface and implementation and enables real code navigation in a framework that defines its dependency graph entirely in XML. Path mappings connect local files to the Docker container and make remote debugging with Xdebug usable.
Together, these three configuration steps turn PhpStorm from an overwhelmed editor into a real IDE for Magento. Autocomplete that knows concrete classes, navigation that resolves interfaces to implementations, and a debugger that breaks inside the Docker container are not extras, they are prerequisites for productive Magento 2 development. The initial investment of about an hour of configuration work pays off every day.
PhpStorm for Magento 2: The Essentials at a Glance
Indexing Excludes
Mark generated/, pub/static/, var/ and node_modules/ as excluded, reduces indexing time by up to 80% and keeps autocomplete precise.
Magento PHPStorm Plugin
Resolves DI interfaces to implementations, navigates to plugins and evaluates di.xml directly. Available on the JetBrains Marketplace.
Memory & Performance
Set -Xmx4096m in VM Options. Configure the PHP interpreter from the Docker container. Put the system temp folder on an SSD.
Path Mappings & Xdebug
Map the local path to the container path /var/www/html. Make debug port 9003 match between PhpStorm and the Xdebug config.