{"id":16390163,"url":"https://github.com/slamdunk/composer-unused-runtime-poc","last_synced_at":"2026-03-12T20:14:21.617Z","repository":{"id":147140677,"uuid":"298800650","full_name":"Slamdunk/composer-unused-runtime-poc","owner":"Slamdunk","description":null,"archived":false,"fork":false,"pushed_at":"2020-09-28T06:10:14.000Z","size":17,"stargazers_count":13,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-04T12:51:09.522Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Slamdunk.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["Slamdunk"],"custom":"https://paypal.me/filippotessarotto"}},"created_at":"2020-09-26T11:34:34.000Z","updated_at":"2020-09-29T14:05:34.000Z","dependencies_parsed_at":"2023-05-16T08:00:26.916Z","dependency_job_id":null,"html_url":"https://github.com/Slamdunk/composer-unused-runtime-poc","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Slamdunk/composer-unused-runtime-poc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Slamdunk%2Fcomposer-unused-runtime-poc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Slamdunk%2Fcomposer-unused-runtime-poc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Slamdunk%2Fcomposer-unused-runtime-poc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Slamdunk%2Fcomposer-unused-runtime-poc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Slamdunk","download_url":"https://codeload.github.com/Slamdunk/composer-unused-runtime-poc/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Slamdunk%2Fcomposer-unused-runtime-poc/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30441857,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-12T14:34:45.044Z","status":"ssl_error","status_checked_at":"2026-03-12T14:09:33.793Z","response_time":114,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-11T04:35:07.705Z","updated_at":"2026-03-12T20:14:21.598Z","avatar_url":"https://github.com/Slamdunk.png","language":"PHP","funding_links":["https://github.com/sponsors/Slamdunk","https://paypal.me/filippotessarotto"],"categories":[],"sub_categories":[],"readme":"# composer-unused-runtime Proof-of-Concept\n\n## Are all your production dependencies truly necessary?\n\n[`composer-unused`](https://github.com/composer-unused/composer-unused) is a needful tool nowadays:\nit looks at your `composer.json/\"require\"` section and checks that every declared production\ndependency is used somewhere, in your code; if it doesn't it suggests to remove it.\n\nThat's great. But a declared dependency can bring along a ton of other dependencies.\n\nAre those **child** dependencies necessary? Do we use them?\n\n1. If our prod doesn't use them, it would be better to avoid installing them altogether:\nthe only code without bugs is in the neverland\n1. If our prod uses them, we should test them!  \n\n## The idea\n\nIf we have 100% Code-Coverage, a full run of our testing framework will populate\n[`get_included_files()`](https://www.php.net/manual/en/function.get-included-files.php) with each and\nevery dependency we use.\n\nDiffing `get_included_files()` output with the list of `composer install --no-dev` installed packages\ncan show the child dependencies that we can prevent altogether to be installed in production, thanks to the\n[`replace`](https://getcomposer.org/doc/04-schema.md#replace) section of `composer.json`.\n\n## The example\n\nThis package calculates the `crc32` checksum of any variable, except closures, because we are silly.\n\nSince we also are lazy, we leverage [`brick/varexporter`](https://github.com/brick/varexporter) for our\ninternal operation.\n\nThe [test](https://github.com/Slamdunk/composer-unused-runtime-poc/blob/master/tests/VarHasherTest.php)\nis simple, and so is the [code](https://github.com/Slamdunk/composer-unused-runtime-poc/blob/master/src/VarHasher.php),\nreaching 100% CC is trivial:\n\n```\n$ vendor/bin/phpunit --coverage-text\nPHPUnit 9.3.11 by Sebastian Bergmann and contributors.\n\n......                                                              6 / 6 (100%)\n\nTime: 00:00.026, Memory: 10.00 MB\n\nOK (6 tests, 6 assertions)\n\n\nCode Coverage Report:   \n  2020-09-26 12:22:09   \n                        \n Summary:               \n  Classes: 100.00% (1/1)\n  Methods: 100.00% (1/1)\n  Lines:   100.00% (1/1)\n```\n\nLet's now list all the installed dependencies in production:\n\n```\n$ composer install --no-dev\n\n$ composer show --format=json | jq --raw-output '.installed[].name' \u003e .installed.txt\n\n$ cat .installed.txt\nbrick/varexporter\nnikic/php-parser\n```\n\n`brick/varexporter` is ok, [we required it in the composer.json](https://github.com/Slamdunk/composer-unused-runtime-poc/blob/master/composer.json#L7).\n\nBut do we need `nikic/php-parser`?\n\nWe can register a shutdown function in the test suite to dump to a\n[file](https://github.com/Slamdunk/composer-unused-runtime-poc/blob/master/.composer-used-runtime.php)\nthe `get_included_files()` output, see\n[`tests/bootstrap.php`](https://github.com/Slamdunk/composer-unused-runtime-poc/blob/master/tests/bootstrap.php),\nand a [simple diff](https://github.com/Slamdunk/composer-unused-runtime-poc/blob/master/composer-unused-runtime.php)\nchecks everything out:\n\n```\n$ php composer-unused-runtime.php \nThe following packages will be installed in production, but are never used during the test suite:\n\nArray\n(\n    [1] =\u003e nikic/php-parser\n)\n```\n\nOk, so now we can strip the dependency out of composer.json:\n\n```diff\n         \"php\": \"^7.4\",\n         \"brick/varexporter\": \"^0.3\"\n     },\n+    \"replace\": {\n+        \"nikic/php-parser\": \"*\"\n+    },\n     \"require-dev\": {\n         \"phpunit/phpunit\": \"^9.3\"\n     },\n```\n\nUpdate the composer.lock and re-run the tests:\n\n```\n$ composer update\nLoading composer repositories with package information\nUpdating dependencies (including require-dev)\nPackage operations: 0 installs, 0 updates, 1 removal\n  - Removing nikic/php-parser (v4.10.2)\nWriting lock file\nGenerating autoload files\n\n$ vendor/bin/phpunit\nPHPUnit 9.3.11 by Sebastian Bergmann and contributors.\n\n......                                                              6 / 6 (100%)\n\nTime: 00:00.007, Memory: 6.00 MB\n\nOK (6 tests, 6 assertions)\n```\n\nNo more unused child dependency will lend in production from now on :rocket:\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslamdunk%2Fcomposer-unused-runtime-poc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fslamdunk%2Fcomposer-unused-runtime-poc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslamdunk%2Fcomposer-unused-runtime-poc/lists"}