{"id":29872722,"url":"https://github.com/canyon-project/canyon","last_synced_at":"2026-04-20T05:00:54.722Z","repository":{"id":39743352,"uuid":"490316875","full_name":"canyon-project/canyon","owner":"canyon-project","description":"Canyon is a JavaScript code coverage solution.","archived":false,"fork":false,"pushed_at":"2026-04-16T02:52:31.000Z","size":16433,"stargazers_count":172,"open_issues_count":2,"forks_count":27,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-04-16T04:29:49.621Z","etag":null,"topics":["ci-cd","coverage","coverage-report","e2e","javascript","js","playwright","self-hosted","testing","unused-code"],"latest_commit_sha":null,"homepage":"https://docs.canyonjs.io","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/canyon-project.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-05-09T14:25:39.000Z","updated_at":"2026-04-16T02:51:40.000Z","dependencies_parsed_at":"2025-11-30T05:05:30.759Z","dependency_job_id":null,"html_url":"https://github.com/canyon-project/canyon","commit_stats":null,"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"purl":"pkg:github/canyon-project/canyon","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canyon-project%2Fcanyon","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canyon-project%2Fcanyon/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canyon-project%2Fcanyon/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canyon-project%2Fcanyon/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/canyon-project","download_url":"https://codeload.github.com/canyon-project/canyon/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canyon-project%2Fcanyon/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32033717,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-20T00:18:06.643Z","status":"online","status_checked_at":"2026-04-20T02:00:06.527Z","response_time":94,"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":["ci-cd","coverage","coverage-report","e2e","javascript","js","playwright","self-hosted","testing","unused-code"],"created_at":"2025-07-30T22:00:48.156Z","updated_at":"2026-04-20T05:00:54.716Z","avatar_url":"https://github.com/canyon-project.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Canyon [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/canyon-project/canyon/blob/main/LICENSE) [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/canyon-project/canyon) [![docker image size](https://img.shields.io/docker/image-size/zhangtao25/canyon/next)](https://hub.docker.com/r/zhangtao25/canyon) [![Made with Prisma](https://made-with.prisma.io/dark.svg)](https://prisma.io) [![Wappalyzer](https://img.shields.io/badge/Detected%20by-Wappalyzer-blue?logo=wappalyzer)](https://www.wappalyzer.com/technologies/development/canyon/)\n\n## Introduction\n\n### Overview\n\nCanyon is a **JavaScript code coverage collection platform**. It tackles the problems developers and QA engineers face when they need **per–test-case** coverage during **end-to-end (E2E) and UI automation** runs.\n\nIt is made up of three main parts:\n\n- A set of [**plugins**](https://github.com/canyon-project/canyon/tree/main/plugins) that integrate with common CI setups and read environment variables.\n- A [**full-stack application**](https://github.com/canyon-project/canyon/tree/main/app) (**Node.js + React**) that ingests and processes coverage data, exposes backend APIs, and renders coverage reports in the browser.\n\n![Canyon home screen](https://cdn.jsdelivr.net/gh/canyon-project/assets/docs/static/docs/getting-started/introduction/home-screen.png)\n\n### Why Canyon?\n\nCanyon **splits hit data and map data at compile time**, so it can handle the **large volumes** of coverage produced by UI automation **efficiently**.\n\nIt also **integrates with common CI providers**: instrumentation is injected at **build** time, and coverage can be **collected and reported** while UI automation runs.\n\nThat way teams can see **accurate**, near–**real-time** coverage **per test case** in UI automation, and use it to judge and improve code quality.\n\n### Features\n\n- **[Accurate and efficient](https://docs.canyonjs.io/docs/core-concepts/separate-hit-and-map)** — separate hit and map; initial coverage data is produced at compile time for reliable, efficient collection.\n- **[Source maps](https://docs.canyonjs.io/docs/core-concepts/restore-source-code-coverage)** — map coverage back to real source code.\n- **[Build tooling](https://docs.canyonjs.io/docs/installation/getting-started)** — coverage flows for stacks such as Next.js, Vite, and Webpack.\n- **[Automation frameworks](https://docs.canyonjs.io/docs/end-to-end-testing/getting-started)** — integration patterns for common UI automation stacks.\n- **[CI providers](https://docs.canyonjs.io/docs/reference/provider)** — GitHub Actions, GitLab CI, and similar runners; CI env detection where applicable.\n\n### Self-hosting\n\nIf you want **full control** over coverage and test metadata, you can **[self-host Canyon](https://docs.canyonjs.io/docs/self-host/community-edition/prerequisites)** on your own infrastructure.\n\n## Ecosystem\n\n| Project | Status | Description |\n| ------- | ------ | ----------- |\n| [@canyonjs/babel-plugin](https://docs.canyonjs.io/docs/ecosystem/babel-plugin) | [![@canyonjs/babel-plugin-status]][@canyonjs/babel-plugin-package] | Babel plugin that detects pipeline / CI environment variables |\n| [@canyonjs/cli](https://docs.canyonjs.io/docs/ecosystem/cli) | [![@canyonjs/cli-status]][@canyonjs/cli-package] | Scans local `.canyon_output` and uploads coverage to the server |\n| [@canyonjs/collect](https://docs.canyonjs.io/docs/ecosystem/collect) | [![@canyonjs/collect-status]][@canyonjs/collect-package] | Browser-side script package for collecting coverage from web apps |\n\n[@canyonjs/babel-plugin-status]: https://img.shields.io/npm/v/@canyonjs/babel-plugin.svg\n[@canyonjs/cli-status]: https://img.shields.io/npm/v/@canyonjs/cli.svg\n[@canyonjs/collect-status]: https://img.shields.io/npm/v/@canyonjs/collect.svg\n[@canyonjs/babel-plugin-package]: https://www.npmjs.com/package/@canyonjs/babel-plugin\n[@canyonjs/cli-package]: https://www.npmjs.com/package/@canyonjs/cli\n[@canyonjs/collect-package]: https://www.npmjs.com/package/@canyonjs/collect\n\n## Architecture\n\nHigh-level flow:\n\n1. A Babel (or compatible) plugin instruments code in your **CI/CD** pipeline.\n2. The app is deployed to a **test** environment; **UI automation** or **manual** testing runs the instrumented code.\n3. Coverage **hits** are reported to the **Canyon server**.\n4. The server stores and processes data, and together with **SCM** source metadata (e.g. GitLab) builds **coverage reports**.\n\n```mermaid\n%%{init: {\n  \"theme\": \"base\",\n  \"themeVariables\": {\n    \"primaryColor\": \"#FFF7ED\",\n    \"primaryBorderColor\": \"#FB923C\",\n    \"lineColor\": \"#9CA3AF\",\n    \"fontFamily\": \"Inter, system-ui\"\n  }\n}}%%\n\nflowchart LR\n  classDef client fill:#EEF2FF,stroke:#6366F1,color:#1E1B4B;\n  classDef test fill:#F1F5F9,stroke:#94A3B8,color:#020617;\n  classDef core fill:#FFF7ED,stroke:#FB923C,color:#7C2D12;\n  classDef storage fill:#ECFEFF,stroke:#06B6D4,color:#083344;\n  classDef infra fill:#F0FDF4,stroke:#22C55E,color:#14532D;\n  classDef external fill:#FAFAFA,stroke:#D1D5DB,color:#111827;\n\n  %% Clients\n  UI[UI Automation]\n  WebUI[Canyon Web UI]\n  API[API Client]\n\n  class UI,WebUI,API client\n\n  %% Test\n  Test[Test Environment]\n  Pipeline[CI / CD Pipeline]\n\n  class Test,Pipeline test\n\n  UI --\u003e Test\n  Pipeline --\u003e Test\n\n  %% Canyon Core\n  subgraph Canyon[\"Canyon Server\"]\n    MQ[Message Queue]\n    DB[(Postgres)]\n    HTTP[HTTP Server]\n  end\n\n  class MQ,HTTP core\n  class DB storage\n\n  Test --\u003e MQ\n  MQ --\u003e DB\n  DB --\u003e HTTP\n\n  %% Infra\n  subgraph Deploy[\"Service Deployment\"]\n    K8s[Kubernetes]\n    Node[Node.js]\n  end\n\n  class K8s,Node infra\n\n  Canyon --\u003e Deploy\n\n  %% External\n  GitLab[GitLab]\n  class GitLab external\n\n  Canyon -.-\u003e GitLab\n\n  WebUI -.-\u003e HTTP\n  API -.-\u003e HTTP\n\n```\n\n\n## WeChat Group\n\n\u003cimg src=\"./screenshots/wechat66.jpg\" style=\"width: 200px\"/\u003e\n\n## Contributing\n\nPlease contribute using [GitHub Flow](https://guides.github.com/introduction/flow). Create a branch, add commits, and [open a pull request](https://github.com/canyon-project/canyon/compare).\n\nPlease read [`CONTRIBUTING`](CONTRIBUTING.md) for details on our [`CODE OF CONDUCT`](CODE_OF_CONDUCT.md), and the process for submitting pull requests to us.\n\n## License\n\nThis project is licensed under the [MIT License](https://opensource.org/licenses/MIT) — see the [`LICENSE`](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcanyon-project%2Fcanyon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcanyon-project%2Fcanyon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcanyon-project%2Fcanyon/lists"}