Complexity Report - how the cyclomatic complexity of PHP open source software evolved over time

Average complexity · year to date
−2.1%
Ø 9.73 → 9.53

PHP open source got less branchy this year - across 804 libraries and 20,681 analysed releases, measured with phploc.

Repositories
822
Releases
20,681
Lines of code
2,340,898,915
Vendors
399
Rankings

Most starred repositories

Draw these 9 in the chart
# Repository Stars Ø Since
01 coollabsio/coolify An open-source, self-hostable PaaS alternative to Vercel, Heroku & Netlify that lets you easily deploy static sites, databases, full-stack applications and 280+ one-click services on your own servers. 60.9k 18.49 ±0.0%
02 nextcloud/server ☁️ Nextcloud server, a safe home for all your data 36.6k 8.43 −82.6%
03 laravel/framework Laravel is a web application framework with expressive, elegant syntax. 34.9k 4.43 +22.5%
04 filamentphp/filament A powerful open-source UI framework for Laravel • Build and ship apps & admin panels fast with Livewire 31.9k 5.32 +141.0%
05 symfony/symfony The Symfony PHP framework 31.1k 6.54 +25.3%
06 composer/composer Dependency Manager for PHP 29.5k 20.90 +56.8%
07 bagisto/bagisto Open Source eCommerce Platform Built with Laravel for Enterprise-Scale Commerce Supporting 10M+ SKUs 28k 4.53 +41.1%
08 fzaninotto/Faker Faker is a PHP library that generates fake data for you 26.7k 2.53 −24.8%
09 monicahq/monica Personal CRM. Remember everything about your friends, family and business relationships. 25.1k 3.29 +22.0%

The order the report itself is built around - stars decide what the chart opens with. Ø is the average cyclomatic complexity of the latest analysed release; the last column is how it moved since the first one.

What the numbers mean

1–10 Simple procedure, little risk
11–20 More complex, moderate risk
21–50 Complex, high risk
> 50 Untestable code, very high risk

How the report is made

Anyone submits a repository, a worker clones it and checks out every major and minor release, and phploc reads every .php file of it and counts sixty-two numbers, the average cyclomatic complexity of a class among them. The clone is deleted, the numbers stay. Every night the report asks github.com what it is missing.

What it is worth

Complexity counts the paths through a class - it says how branchy the average class of a library is, not how large or how good it is. Committed dependencies and generated code count towards it, and libraries that were split or renamed carry jumps their git history cannot explain.

How a repository gets in

github.com is the only source, and no composer.json is needed. A submission is turned down when the repository is unknown, a fork, empty, larger than 10 GB, or less than 20% PHP by the language breakdown github.com reports for it; everything else is queued for a worker.

The worker clones it and checks out its release tags one after another. Only major and minor releases are measured (5.4, 5.4.0) - patch releases and pre-releases (anything carrying a -) are skipped, as are a handful of releases whose date git cannot tell straight. On every checkout phploc reads every .php file of the working copy and leaves its whole measurement behind - sixty-two numbers, dated by the last commit that tag points at, and every one of them can be drawn over the years.

From then on the report keeps itself current: every night it refreshes stars and asks github.com which releases are missing, so a new minor turns up in the chart by itself - and a repository that did not release is not even cloned.

About cyclomatic complexity

Cyclomatic complexity counts the paths through a piece of code: one, plus one for every branch - if, case, while, for, catch, &&, ||. Code without a single condition scores 1. What is charted here is the average over all classes of a release.

It is one metric, and worth what a metric is worth. It travels well as a rough measure of how many paths a test suite has to cover, and badly as a verdict: a clear class holding one big match outscores a tangle of indirection nobody can follow, and pushing branches into polymorphism lowers the figure without lowering the thinking. The shape of a line over the years says more than any point on it.

The data has its glitches, too. Whatever sits in a repository at a tag is measured, so committed dependencies, generated code and test suites count towards the average. Libraries that were split, renamed or imported from another version control system - Zend → Laminas, the early PHPUnit tags - carry dates and jumps their git history cannot explain. And a gap in a line is a release that was left out or could not be measured - not one that never happened.