{"id":49219733,"url":"https://github.com/ahilke/js-crap-score","last_synced_at":"2026-04-24T02:01:16.088Z","repository":{"id":145471516,"uuid":"610963068","full_name":"ahilke/js-crap-score","owner":"ahilke","description":"Calculate and visualize the CRAP score of a JS/TS project using the provided `jest` integration, CLI, or API.","archived":false,"fork":false,"pushed_at":"2026-04-24T01:10:56.000Z","size":622,"stargazers_count":10,"open_issues_count":7,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-24T01:36:43.269Z","etag":null,"topics":["code-quality","crap-score","cyclomatic-complexity","javascript","test-coverage","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ahilke.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","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}},"created_at":"2023-03-07T20:43:04.000Z","updated_at":"2026-04-24T01:09:52.000Z","dependencies_parsed_at":null,"dependency_job_id":"fb6ae1a1-c066-42a1-8f1c-f47975c1df78","html_url":"https://github.com/ahilke/js-crap-score","commit_stats":{"total_commits":152,"total_committers":3,"mean_commits":"50.666666666666664","dds":0.09868421052631582,"last_synced_commit":"50eee4b523874c743ac9438ff01c484c11184d46"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/ahilke/js-crap-score","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahilke%2Fjs-crap-score","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahilke%2Fjs-crap-score/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahilke%2Fjs-crap-score/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahilke%2Fjs-crap-score/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ahilke","download_url":"https://codeload.github.com/ahilke/js-crap-score/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahilke%2Fjs-crap-score/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32205942,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-24T01:12:49.758Z","status":"online","status_checked_at":"2026-04-24T02:00:07.115Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["code-quality","crap-score","cyclomatic-complexity","javascript","test-coverage","typescript"],"created_at":"2026-04-24T02:01:15.334Z","updated_at":"2026-04-24T02:01:16.080Z","avatar_url":"https://github.com/ahilke.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CRAP Score\n\n[![npm version](https://badge.fury.io/js/crap-score.svg)](https://badge.fury.io/js/crap-score)\n\nUse CRAP to estimate and visualize the change risk of your JS/TS project.\n\n-   [Example](#example)\n-   [What is CRAP?](#what-is-crap)\n-   [How to Use](#how-to-use)\n    -   [Jest Reporter](#jest-reporter)\n    -   [CLI](#cli)\n    -   [API](#api)\n    -   [istanbul JSON Coverage Report](#istanbul-json-coverage-report)\n-   [Contributing](#contributing)\n\n## Example\n\nThe HTML CRAP report of the project itself can be found under \u003chttps://ahilke.github.io/js-crap-score/\u003e.\n\n## What is CRAP?\n\nThe CRAP score is a measure of the risk of a function ranging from 1 (best) to infinity (worst). It uses complexity and coverage information to give an estimate how likely it is that a function contains bugs or breaks with future changes.\n\nCRAP is an acronym for Change Risk Anti-Patterns and is computed as follows: $comp^2 \\cdot (1 - cov)^3 + comp$, where `comp` is the cyclomatic complexity of the function and `cov` is the statement coverage as number between 0 (no coverage) and 1 (fully covered).\n\nA common guideline is to address functions with a CRAP score above 30 by either adding additional tests or refactoring the function to reduce complexity. This translates to simple functions with complexity 5 or lower not requiring any test coverage, while a function with complexity over 30 always requires refactoring.\n\n## How to Use\n\nThis package provides multiple ways to generate and collect information about coverage, complexity and CRAP for each function within your project. It generates both a human-readable HTML report and a JSON report for further processing.\n\nUsage Options:\n\n-   run it together with your tests by adding it to your [jest configuration](#jest-reporter)\n-   run it from the [command line](#cli)\n-   integrate it into your [own program](#api)\n\n### Jest Reporter\n\nAdd `crap-score` as [test reporter](https://jestjs.io/docs/configuration#reporters-arraymodulename--modulename-options) to jest.\nWhen `jest` is run with coverage enabled, this will also generate a CRAP report. Example for `jest.config.json`:\n\n```json\n\"reporters\": [\"default\", \"crap-score\"]\n```\n\nThe reporter also accepts options, for example:\n\n```json\n\"reporters\": [\n    \"default\",\n    [\n        \"crap-score\",\n        {\n            \"jsonReportFile\": \"crap.json\",\n        }\n    ]\n]\n```\n\nA typed interface for the reporter options is available via `import type { ReporterOptions } from \"crap-score\";`.\n\nAvailable options:\n\n| Option         | Description                                                                                                                               |\n| -------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |\n| jsonReportFile | Specifies path where the JSON report will be written to. Defaults to `crap-report/crap-report.json`. Pass `false` to disable JSON report. |\n| htmlReportDir  | Specifies path where the HTML report will be written to. Defaults to `crap-report/html/`. Pass `false` to disable HTML report.            |\n| log            | Changes log behaviour. `\"silent\"` suppresses all logs. `\"debug\"` prints additional logs.                                                  |\n\n### CLI\n\nInstall the package (or use it directly via npx), then just run `npx crap \u003cpath-to-coverage\u003e`.\nThe command expects an istanbul JSON coverage report as input (see [JSON Coverage Report](#istanbul-json-coverage-report)) and generates both an HTML and a JSON report in the `crap-report` folder, containing the CRAP score of each function in the original istanbul report.\n\n```sh\ncrap --help\n```\n\n### API\n\n#### ESM\n\n```ts\nimport { getCrapReport, CrapReport } from \"crap-score\";\n\nconst report: CrapReport = await getCrapReport({\n    testCoverage: \"./coverage/coverage-final.json\",\n});\n```\n\n#### CommonJS\n\nTo use the library API in a CommonJS project, you will need to use dynamic `import` statements as this is a ESM library:\n\n```ts\nasync function main() {\n    const { getCrapReport } = await import(\"crap-score\");\n    const report = await getCrapReport({\n        testCoverage: \"./coverage/coverage-final.json\",\n    });\n}\n```\n\nIf you are using TypeScript, make sure to have `\"moduleResolution\": \"node16\"` to avoid `import` being transformed into `require`. If that is not an option, you can work around it via `eval`:\n\n```ts\nasync function main() {\n    const { getCrapReport } = await eval(\"import('crap-score')\");\n    const report = await getCrapReport({\n        testCoverage: \"./coverage/coverage-final.json\",\n    });\n}\n```\n\n### istanbul JSON Coverage Report\n\nIf you are using `jest`, you can generate an istanbul JSON coverage report by adding `collectCoverage: true` and `coverageReporters: [\"json\"]` to your configuration. This will generate a JSON report under `coverage-final.json`.\n\nMake sure to also review other configuration related to coverage, especially `collectCoverageFrom`. This allows you to include files in your report even if they are not covered. This is important, since any uncovered function in your project may have a very high CRAP score.\n\n## Contributing\n\nGot any feedback? I'm eager to hear it! Please open an issue or send me an email.\n\nIf you want to contribute code, please read [CONTRIBUTING.md](./CONTRIBUTING.md) first.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fahilke%2Fjs-crap-score","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fahilke%2Fjs-crap-score","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fahilke%2Fjs-crap-score/lists"}