Search by

symplify / easy-coding-standard

Use Coding Standard with 0-knowledge of PHP-CS-Fixer and PHP_CodeSniffer

Maintainers

Package info

github.com/ecsphp/ecs

pkg:composer/symplify/easy-coding-standard

Transparency log

Statistics

Installs: 39 433 366

Dependents: 1 690

Suggesters: 8

Stars: 1 623

13.2.19 2026-08-24 17:02 UTC

This package is auto-updated.

Last update: 2026-09-05 10:46:39 UTC


README

Downloads total

Easy Coding Standard (ECS) is a single tool that runs PHP_CodeSniffer and PHP-CS-Fixer rules together, configured through one simple PHP file.

Note

This is the deployed package. Development happens in the ecs-src repository - report issues and send pull requests there.


Killer Features


Install

composer require symplify/easy-coding-standard --dev

Usage

vendor/bin/ecs

On the first run, ECS creates ecs.php config file with directories and first rule to kick off.

Then you can run again to see the suggested diffs:

vendor/bin/ecs

Want to check specific paths instead of the configured ones? Pass them as arguments:

vendor/bin/ecs src tests

To actually fix your code, add --fix:

vendor/bin/ecs --fix

That's it!


Configure

Most of the time, you'll be happy with the default configuration. The most relevant part is configuring paths, checkers and sets:

use PhpCsFixer\Fixer\ArrayNotation\ArraySyntaxFixer;
use PhpCsFixer\Fixer\ListNotation\ListSyntaxFixer;
use Symplify\EasyCodingStandard\Config\ECSConfig;

return ECSConfig::configure()
    ->withPaths([__DIR__ . '/src', __DIR__ . '/tests'])

    // start slow with sole rules
    ->withRules([
        ListSyntaxFixer::class,
    ])
    ->withConfiguredRule(
        ArraySyntaxFixer::class,
        ['syntax' => 'long']
    )

    // apply full set
    ->withPreparedSets(psr12: true);

Do you want to check all *.php files in your root (ecs.php, rector.php etc.)? Instead of listing them one by one, use ->withRootFiles() method:

use Symplify\EasyCodingStandard\Config\ECSConfig;

return ECSConfig::configure()
    ->withPaths([__DIR__ . '/src', __DIR__ . '/tests'])
    ->withRootFiles();

Prepared Sets

->withPreparedSets() bundles curated rule sets. Enable the whole common set, or pick single topics:

use Symplify\EasyCodingStandard\Config\ECSConfig;

return ECSConfig::configure()
    ->withPaths([__DIR__ . '/src', __DIR__ . '/tests'])
    ->withPreparedSets(
        arrays: true,
        spaces: true,
        namespaces: true,
        docblocks: true,
        controlStructures: true,
        comments: true,
        casing: true,
        cleanup: true,
    );
Set What it covers
arrays array syntax, spacing, trailing commas, indentation
spaces whitespace, operator/type spacing, blank lines
namespaces imports ordering, unused/needless-alias imports
docblocks phpdoc tags, types, alignment, cleanup
controlStructures control flow, casing, operators, class structure
comments comment style, spacing, empty-comment cleanup
casing native function/type, magic method, literal casing
cleanup dead statements, useless returns/casts, unused closure imports

Or enable everything at once with ->withPreparedSets(common: true).


Gradual Adoption with Levels

Want to adopt a coding standard step by step instead of all at once? Use with*Level() methods to start from the safest rules and raise the level as your codebase catches up:

use Symplify\EasyCodingStandard\Config\ECSConfig;

return ECSConfig::configure()
    ->withPaths([__DIR__ . '/src', __DIR__ . '/tests'])
    ->withSpacesLevel(0)
    ->withArrayLevel(0)
    ->withControlStructuresLevel(0)
    ->withDocblockLevel(0);

Each level enables the first N+1 rules from a curated list, ordered from safest to most invasive. Bump the number once your codebase is clean on the current level.


How to Skip Files/Rules?

Love the sets of rules, but want to skip single rule or some files?

use Symplify\EasyCodingStandard\Config\ECSConfig;

return ECSConfig::configure()
    ->withSkip([
        // skip single rule
        ArraySyntaxFixer::class,

        // skip single rule in specific paths
        ArraySyntaxFixer::class => [
            __DIR__ . '/src/ValueObject/',
        ],

        // skip directory by absolute or * mask
        __DIR__ . '/src/Migrations',

        // skip directories by mask
        __DIR__ . '/src/*/Legacy',
    ]);

Less Common Options

You probably won't use these, but they can give you more control over the internal process:

use Symplify\EasyCodingStandard\Config\ECSConfig;
use Symplify\EasyCodingStandard\ValueObject\Option;

return ECSConfig::configure()
    // file extensions to scan
    ->withFileExtensions(['php'])

    // configure cache paths and namespace - useful e.g. Gitlab CI caching, where getcwd() produces always different path
    ->withCache(
        directory: sys_get_temp_dir() . '/_changed_files_detector_tests',
        namespace: getcwd() // normalized to directory separator
    )

    // print contents with specific indent rules
    ->withSpacing(indentation: Option::INDENTATION_SPACES, lineEnding: PHP_EOL)

    // modify parallel run
    ->withParallel(timeoutSeconds: 120, maxNumberOfProcess: 32, jobSize: 20);

Mentioned values are default ones.


Controlling Output Format

You may want to use ECS to generate reports for third-party tooling.

We currently provide formatters for:

  • console: Human-oriented printing à la PHP CS Fixer.
  • json: A custom JSON blob for arbitrary tooling.
  • checkstyle: Useful for Github Action Reports.

You can use the output format option as below

vendor/bin/ecs --output-format=checkstyle

FAQ

How do I clear cache?

vendor/bin/ecs --clear-cache

How can I see all used rules?

vendor/bin/ecs list-checkers

Do you look for json format?

vendor/bin/ecs list-checkers --output-format json

How to Migrate from another coding standard tool?

Do you use another tool and want to migrate? It's pretty straightforward - here is "how to":