PHPackages                             bmitch/churn-php - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. bmitch/churn-php

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

bmitch/churn-php
================

Discover files in need of refactoring.

1.7.3(4mo ago)1.4k1.5M↓19.5%58[4 issues](https://github.com/bmitch/churn-php/issues)12MITPHPPHP &gt;=7.1.3CI passing

Since Jun 20Pushed 4mo ago16 watchersCompare

[ Source](https://github.com/bmitch/churn-php)[ Packagist](https://packagist.org/packages/bmitch/churn-php)[ Docs](https://github.com/bmitch/churn-php)[ RSS](/packages/bmitch-churn-php/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (10)Versions (30)Used By (12)

churn-php
=========

[](#churn-php)

Helps discover good candidates for refactoring.

[![Build Status](https://github.com/bmitch/churn-php/workflows/Continuous%20Integration/badge.svg)](https://github.com/bmitch/churn-php/actions)[![codecov](https://camo.githubusercontent.com/cfaa23f87b94485a16985bd76d5777f8688fadae8dcebeb9a6c1ce03e5015e2e/68747470733a2f2f636f6465636f762e696f2f67682f626d697463682f636875726e2d7068702f6272616e63682f6d61737465722f67726170682f62616467652e737667)](https://codecov.io/gh/bmitch/churn-php)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/bdfe5a610871297151dc56814cb2eb8c031a01f78c1cdd62edd88cc3686e4d96/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f626d697463682f636875726e2d7068702f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/bmitch/churn-php/?branch=master)[![Code Climate](https://camo.githubusercontent.com/5c8cf59d49acc63bfef2203a047b8a87802da73941fee83ece7cad309e72dac3/68747470733a2f2f636f6465636c696d6174652e636f6d2f6769746875622f626d697463682f636875726e2d7068702f6261646765732f6770612e737667)](https://codeclimate.com/github/bmitch/churn-php)[![Packagist](https://camo.githubusercontent.com/f32e78581236508f8407a37ec6f2923b45454d3f337183b7a3c1197cfd00e79a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f626d697463682f636875726e2d7068702e737667)](https://packagist.org/packages/bmitch/churn-php)[![Packagist](https://camo.githubusercontent.com/2d68c2d62e646de1ef1a0fedad4de320712e026343d4ff019a3ed3faed22206f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f626d697463682f636875726e2d7068702e737667)](https://packagist.org/packages/bmitch/churn-php/stats)[![Packagist](https://camo.githubusercontent.com/99986369771e5082c07af1f5afbd9e42955e39e055e1d60aa0538da9cfefcdc9/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f626d697463682f636875726e2d7068702e737667)](LICENSE.md)[![Donate](https://camo.githubusercontent.com/604e3db9c8751116b3f765aad0353ec7ded655bbe8aaacbc38d8c4a6b784b3ed/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f446f6e6174652d50617950616c2d677265656e2e737667)](https://paypal.me/bmitch2112)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

[](#)

Table of Contents
-----------------

[](#table-of-contents)

- [What Is it?](#what-is-it)
- [Compatibility](#compatibility)
- [How to Install?](#how-to-install)
- [How to Use?](#how-to-use)
- [How to Configure?](#how-to-configure)
- [Similar Packages](#similar-packages)
- [Contact](#contact)
- [Contributing](#contributing)
- [License](#license)

What is it?
-----------

[](#what-is-it)

`churn-php` is a package that helps you identify php files in your project that could be good candidates for refactoring. It examines each PHP file in the path it is provided and:

- Checks how many commits it has.
- Calculates the cyclomatic complexity.
- Creates a score based on these two values.

The results are displayed in a table:

[![](img/output.png)](img/output.png)

A file that changes a lot and has a high complexity might be a better candidate for refactoring than a file that doesn't change a lot and has a low complexity.

`churn-php` only assists the developer to identify files for refactoring. It's best to use the results in addition to your own judgment to decide which files you may want to refactor.

Compatibility
-------------

[](#compatibility)

- PHP 7.1+
- Composer 2.0+

How to Install?
---------------

[](#how-to-install)

Download the [last release](https://github.com/bmitch/churn-php/releases/latest) of `churn.phar`or install it with [Phive](https://phar.io/):

```
phive install churn
```

You can also install `churn-php` via Composer:

```
composer require bmitch/churn-php --dev
```

How to Use?
-----------

[](#how-to-use)

```
churn run  ...
churn run src
churn run src tests

# the command name can be skipped if directoriesToScan is set in churn.yml
churn
```

How to Configure?
-----------------

[](#how-to-configure)

You may add an optional `churn.yml` file which can be used to configure churn-php. The location of this file can be customized using the `--configuration` option:

```
# Default: "churn.yml" or "churn.yml.dist"
churn run --configuration=config-dir/
churn run --configuration=my-config.yml
```

A sample `churn.yml` file looks like:

```
# The maximum number of files to display in the results table.
# Default: 10
filesToShow: 10

# The minimum score a file need to display in the results table.
# Disabled if null.
# Default: 0.1
minScoreToShow: 0

# The command returns an 1 exit code if the highest score is greater than the threshold.
# Disabled if null.
# Default: null
maxScoreThreshold: 0.9

# The number of parallel jobs to use when processing files.
# Default: 10
parallelJobs: 10

# How far back in the VCS history to count the number of commits to a file
# Can be a human readable date like 'One week ago' or a date like '2017-07-12'
# Default: '10 Years ago'
commitsSince: One year ago

# Files to ignore when processing. The full path to the file relative to the root of your project is required.
# Also supports regular expressions.
# Default: All PHP files in the path provided to churn-php are processed.
filesToIgnore:
 - src/Commands/ChurnCommand.php
 - src/Results/ResultsParser.php
 - src/Foo/Ba*

# File extensions to use when processing.
# Default: php
fileExtensions:
 - php
 - inc

# This list is used only if there is no argument when running churn.
# Default:
directoriesToScan:
 - src
 - tests/

# List of user-defined hooks.
# They can be referenced by their full qualified class name if churn has access to the autoloader.
# Otherwise the file path can be used as well.
# See below the section about hooks for more details.
# Default:
hooks:
 - Namespace\MyHook
 - path/to/my-hook.php

# The version control system used for your project.
# Accepted values: fossil, git, mercurial, subversion, none
# Default: git
vcs: git

# The path of the cache file. It doesn't need to exist before running churn.
# Disabled if null.
# Default: null
cachePath: .churn.cache
```

If a `churn.yml` file is omitted or an individual setting is omitted the default values above will be used.

### Output formats

[](#output-formats)

You can configure `churn` to output the result in different formats. The available formats are:

- `csv`
- `json`
- `markdown`
- `text` (default)

To use a different format use `--format` option. Example command for `json`:

```
churn run --format json
```

### Hooks

[](#hooks)

The *hooks* configuration allows you to customize `churn`.

A user-defined hook must implement at least one Hook interface:

Hook interfaceCorresponding event interface[AfterAnalysisHook](src/Event/Hook/AfterAnalysisHook.php)[AfterAnalysis](src/Event/Event/AfterAnalysis.php)[AfterFileAnalysisHook](src/Event/Hook/AfterFileAnalysisHook.php)[AfterFileAnalysis](src/Event/Event/AfterFileAnalysis.php)[BeforeAnalysisHook](src/Event/Hook/BeforeAnalysisHook.php)[BeforeAnalysis](src/Event/Event/BeforeAnalysis.php)Similar Packages
----------------

[](#similar-packages)

-  (Ruby)
-  (Ruby)

Contact
-------

[](#contact)

Questions, comments, feedback? [@bmitch2112](https://twitter.com/bmitch2112)

Contributing
------------

[](#contributing)

- Please run `composer test` on PHP 7.1 and ensure it passes.
- If you don't have access to PHP 7.1 please make sure that CI build passes when you make pull request. If you are unable to get it to pass in the pull request please ping me and I can help.
- Please see [CONTRIBUTING.md](CONTRIBUTING.md)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

65

—

FairBetter than 99% of packages

Maintenance75

Regular maintenance activity

Popularity64

Solid adoption and visibility

Community39

Small or concentrated contributor base

Maturity69

Established project with proven stability

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~111 days

Recently: every ~356 days

Total

29

Last Release

139d ago

Major Versions

0.5.0 → 1.0.02018-07-04

PHP version history (4 changes)0.0.1PHP &gt;=7.0.0

0.1.0PHP ^7.0

1.0.0PHP ^7.1.3

1.3.0PHP &gt;=7.1.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/581585b68bc8e4418bfefd6918579de4b277539f1c98a478bf044750eb64ae93?d=identicon)[bmitch](/maintainers/bmitch)

---

Top Contributors

[![bmitch](https://avatars.githubusercontent.com/u/4009957?v=4)](https://github.com/bmitch "bmitch (204 commits)")[![villfa](https://avatars.githubusercontent.com/u/2891564?v=4)](https://github.com/villfa "villfa (200 commits)")[![bearzk](https://avatars.githubusercontent.com/u/775611?v=4)](https://github.com/bearzk "bearzk (11 commits)")[![localheinz](https://avatars.githubusercontent.com/u/605483?v=4)](https://github.com/localheinz "localheinz (9 commits)")[![vrishank97](https://avatars.githubusercontent.com/u/14790428?v=4)](https://github.com/vrishank97 "vrishank97 (6 commits)")[![matthiasnoback](https://avatars.githubusercontent.com/u/1193078?v=4)](https://github.com/matthiasnoback "matthiasnoback (6 commits)")[![riverrun46](https://avatars.githubusercontent.com/u/4689219?v=4)](https://github.com/riverrun46 "riverrun46 (5 commits)")[![joezidell-saleswarp](https://avatars.githubusercontent.com/u/20782869?v=4)](https://github.com/joezidell-saleswarp "joezidell-saleswarp (4 commits)")[![rmikalkenas](https://avatars.githubusercontent.com/u/14221532?v=4)](https://github.com/rmikalkenas "rmikalkenas (4 commits)")[![nhoag](https://avatars.githubusercontent.com/u/1390106?v=4)](https://github.com/nhoag "nhoag (4 commits)")[![szepeviktor](https://avatars.githubusercontent.com/u/952007?v=4)](https://github.com/szepeviktor "szepeviktor (4 commits)")[![gahlawat](https://avatars.githubusercontent.com/u/4440677?v=4)](https://github.com/gahlawat "gahlawat (3 commits)")[![raphaelstolt](https://avatars.githubusercontent.com/u/48225?v=4)](https://github.com/raphaelstolt "raphaelstolt (3 commits)")[![Nyholm](https://avatars.githubusercontent.com/u/1275206?v=4)](https://github.com/Nyholm "Nyholm (2 commits)")[![dmytro-y-dev](https://avatars.githubusercontent.com/u/5102404?v=4)](https://github.com/dmytro-y-dev "dmytro-y-dev (2 commits)")[![simPod](https://avatars.githubusercontent.com/u/327717?v=4)](https://github.com/simPod "simPod (2 commits)")[![tommy-muehle](https://avatars.githubusercontent.com/u/1351840?v=4)](https://github.com/tommy-muehle "tommy-muehle (2 commits)")[![frazjp65](https://avatars.githubusercontent.com/u/13321887?v=4)](https://github.com/frazjp65 "frazjp65 (1 commits)")[![gms8994](https://avatars.githubusercontent.com/u/50712?v=4)](https://github.com/gms8994 "gms8994 (1 commits)")[![GaryJones](https://avatars.githubusercontent.com/u/88371?v=4)](https://github.com/GaryJones "GaryJones (1 commits)")

---

Tags

clean-codecomplexitycontinuous-integrationidentify-filesphprefactorstatic analysisrefactoringcomplexitychurn

### Embed Badge

![Health badge](/badges/bmitch-churn-php/health.svg)

```
[![Health](https://phpackages.com/badges/bmitch-churn-php/health.svg)](https://phpackages.com/packages/bmitch-churn-php)
```

###  Alternatives

[symfony/maker-bundle

Symfony Maker helps you create empty commands, controllers, form classes, tests and more so you can forget about writing boilerplate code.

3.4k111.1M568](/packages/symfony-maker-bundle)[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.4k5.6M651](/packages/sylius-sylius)[infection/infection

Infection is a Mutation Testing framework for PHP. The mutation adequacy score can be used to measure the effectiveness of a test set in terms of its ability to detect faults.

2.2k26.2M1.8k](/packages/infection-infection)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.3M152](/packages/sulu-sulu)[shopware/platform

The Shopware e-commerce core

3.3k1.5M3](/packages/shopware-platform)[symplify/monorepo-builder

Not only Composer tools to build a Monorepo.

5205.3M82](/packages/symplify-monorepo-builder)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
