{"id":50665678,"url":"https://github.com/saadjs/gh-stats","last_synced_at":"2026-06-08T06:04:52.247Z","repository":{"id":335917553,"uuid":"1147460996","full_name":"saadjs/gh-stats","owner":"saadjs","description":"npx @saadjs/gh-stats --help","archived":false,"fork":false,"pushed_at":"2026-02-18T04:40:29.000Z","size":123,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-18T09:39:40.769Z","etag":null,"topics":["cli","github","github-stats","top-languages"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/saadjs.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-01T19:26:02.000Z","updated_at":"2026-02-18T04:40:29.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/saadjs/gh-stats","commit_stats":null,"previous_names":["saadjs/gh-stats"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/saadjs/gh-stats","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saadjs%2Fgh-stats","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saadjs%2Fgh-stats/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saadjs%2Fgh-stats/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saadjs%2Fgh-stats/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/saadjs","download_url":"https://codeload.github.com/saadjs/gh-stats/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saadjs%2Fgh-stats/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34050243,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-08T02:00:07.615Z","response_time":111,"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":["cli","github","github-stats","top-languages"],"created_at":"2026-06-08T06:04:34.341Z","updated_at":"2026-06-08T06:04:52.241Z","avatar_url":"https://github.com/saadjs.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# gh-stats\n\nGenerate GitHub language stats as JSON or SVG charts with multiple themes.\n\n## Requirements\n\n- Node.js 18+ (for built-in `fetch`)\n- pnpm 10 (see `packageManager` in `package.json`)\n- A GitHub token with access to private repositories if needed\n\n## Setup\n\n```bash\npnpm install\npnpm run build\n```\n\n## Usage\n\n## Run with npx (no install)\n\n```bash\nGITHUB_TOKEN=your_token npx @saadjs/gh-stats --svg --out stats.svg\n```\n\n```bash\nnpx @saadjs/gh-stats --svg --theme phosphor --in data.json --out stats.svg\n```\n\n## Install CLI command\n\nBuild first, then link globally or install from the local path.\n\n```bash\npnpm run build\npnpm link --global\n```\n\nOr:\n\n```bash\npnpm run build\npnpm add -g .\n```\n\n### JSON (default)\n\n```bash\nGITHUB_TOKEN=your_token gh-stats\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eJSON schema (for custom inputs)\u003c/summary\u003e\n\n```json\n{\n  \"type\": \"object\",\n  \"required\": [\n    \"totalBytes\",\n    \"languages\",\n    \"generatedAt\",\n    \"repositoryCount\",\n    \"includedForks\",\n    \"includedArchived\",\n    \"includedMarkdown\"\n  ],\n  \"properties\": {\n    \"totalBytes\": { \"type\": \"number\" },\n    \"languages\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"type\": \"object\",\n        \"required\": [\"language\", \"bytes\", \"percent\"],\n        \"properties\": {\n          \"language\": { \"type\": \"string\" },\n          \"bytes\": { \"type\": \"number\" },\n          \"percent\": { \"type\": \"number\" }\n        },\n        \"additionalProperties\": false\n      }\n    },\n    \"generatedAt\": { \"type\": \"string\", \"format\": \"date-time\" },\n    \"repositoryCount\": { \"type\": \"number\" },\n    \"includedForks\": { \"type\": \"boolean\" },\n    \"includedArchived\": { \"type\": \"boolean\" },\n    \"includedMarkdown\": { \"type\": \"boolean\" },\n    \"analysisSource\": { \"type\": \"string\", \"enum\": [\"api\", \"clone\"] },\n    \"analysisMethod\": { \"type\": \"string\", \"enum\": [\"repo_bytes\", \"changed_lines\"] },\n    \"engine\": { \"type\": \"string\", \"enum\": [\"github-linguist\"] },\n    \"skippedRepositories\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"type\": \"object\",\n        \"required\": [\"fullName\", \"reason\"],\n        \"properties\": {\n          \"fullName\": { \"type\": \"string\" },\n          \"reason\": { \"type\": \"string\" }\n        },\n        \"additionalProperties\": false\n      }\n    },\n    \"window\": {\n      \"type\": \"object\",\n      \"required\": [\"days\", \"since\", \"until\", \"activityField\"],\n      \"properties\": {\n        \"days\": { \"type\": \"number\" },\n        \"since\": { \"type\": \"string\", \"format\": \"date-time\" },\n        \"until\": { \"type\": \"string\", \"format\": \"date-time\" },\n        \"activityField\": { \"type\": \"string\", \"enum\": [\"pushed_at\", \"changed_lines\"] }\n      },\n      \"additionalProperties\": false\n    }\n  },\n  \"additionalProperties\": false\n}\n```\n\n\u003c/details\u003e\n\n### SVG\n\n```bash\nGITHUB_TOKEN=your_token gh-stats --svg --out stats.svg\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eTheme previews\u003c/summary\u003e\n\n**--theme default**\n![--theme default preview](./assets/theme-default.svg)\n\n**--theme phosphor**\n![--theme phosphor preview](./assets/theme-phosphor.svg)\n\n**--theme infrared**\n![--theme infrared preview](./assets/theme-infrared.svg)\n\n**--theme outline**\n![--theme outline preview](./assets/theme-outline.svg)\n\n**--theme pie**\n![--theme pie preview](./assets/theme-pie.svg)\n\n\u003c/details\u003e\n\n### Cache JSON once, render SVG offline\n\nGenerate the JSON once, then re-render SVGs with different themes without hitting the GitHub API.\n\n```bash\nGITHUB_TOKEN=your_token gh-stats --json --out data.json\n```\n\n```bash\ngh-stats --svg --theme phosphor --in data.json --out stats.svg\ngh-stats --svg --theme infrared --in data.json --out stats.svg\ngh-stats --svg --theme pie --in data.json --out stats.svg\n```\n\n## Keeping stats updated (profile README)\n\nUse a scheduled GitHub Actions workflow to regenerate `stats.svg` and commit it back to the\nprofile README repo (`\u003cusername\u003e/\u003cusername\u003e`).\n\n\u003cdetails\u003e\n\n\u003csummary\u003eExample workflow setup\u003c/summary\u003e\n\nCreate `.github/workflows/update-stats.yml` in the profile repo:\n\n```yaml\nname: Update GH Stats\n\non:\n  schedule:\n    - cron: \"0 6 * * *\" # daily at 06:00 UTC\n  workflow_dispatch:\n\npermissions:\n  contents: write\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: pnpm/action-setup@v3\n        with:\n          version: 10\n      - uses: actions/setup-node@v4\n        with:\n          node-version: 20\n          cache: pnpm\n\n      - run: pnpm install\n      - run: pnpm run build\n      - run: GITHUB_TOKEN=${{ secrets.GH_TOKEN || secrets.GITHUB_TOKEN }} gh-stats --svg --out stats.svg\n\n      - run: |\n          if [[ -n \"$(git status --porcelain)\" ]]; then\n            git config user.name \"github-actions[bot]\"\n            git config user.email \"github-actions[bot]@users.noreply.github.com\"\n            git add stats.svg\n            git commit -m \"chore: update language stats\"\n            git push\n          fi\n```\n\n\u003c/details\u003e\n\nNotes:\n\n- For public-only stats, `GITHUB_TOKEN` is enough.\n- For private repos, add a PAT as `GH_TOKEN` in repo secrets (with `repo` scope).\n- Embed the SVG in your profile `README.md` with `![GitHub language stats](./stats.svg)`.\n\n### Options\n\n- `--token \u003ctoken\u003e` GitHub access token (or use `GITHUB_TOKEN`)\n- `--format \u003cjson|svg\u003e` choose output format\n- `--json` output JSON\n- `--svg` output SVG\n- `--theme \u003cname\u003e` choose SVG theme: default, phosphor, infrared, outline, pie\n- `--in \u003cpath\u003e` read precomputed stats JSON (skips GitHub API)\n- `--include-forks` include forked repositories (default: excluded)\n- `--exclude-archived` exclude archived repositories (default: included)\n- `--include-markdown` include Markdown/MDX in language stats (default: excluded)\n- `--past-week` past 7-day activity (filters to repos pushed in last 7 days)\n- `--source \u003capi|clone\u003e` choose analysis source (default: api)\n- `--clone-concurrency \u003cn\u003e` max concurrent clones in clone mode (default: 3)\n- `--tmp-dir \u003cpath\u003e` temp directory for clone mode (default: OS temp dir)\n- `--linguist-engine \u003clocal|docker\u003e` choose github-linguist engine (default: local)\n- `--author \u003cusername\u003e` limit clone past-week churn to one author\n- `--all-authors` include all authors in clone past-week mode\n- `--include-markup-langs` include markup/config languages (JSON, YAML, HTML, XML, etc.)\n- `--include-repo-composition` include full repo composition alongside weekly churn in clone past-week mode\n- `--cache-dir \u003cpath\u003e` cache directory for cloned repositories\n- `--no-cache` disable clone cache\n- `--top \u003cn\u003e` limit to top N languages (default: 10)\n- `--all` include all languages (overrides `--top`)\n- `--out \u003cpath\u003e` write output to a file\n- `--help` / `-h` show help\n\n### Analysis sources\n\n`--source api` (default)\n\n- Uses GitHub's languages API (repo byte totals).\n- `--past-week` filters repos by `pushed_at`, then aggregates full repo bytes.\n\n`--source clone`\n\n- Clones repositories locally and runs `github-linguist` for language detection.\n- Requires `git` and either `github-linguist` (local) or `docker` (docker engine) on your PATH.\n- `--past-week` first filters repos by `pushed_at`, then aggregates line churn ($added + deleted$) from the last 7 days per language.\n- For author-filtered past-week mode, repos are additionally prefiltered via GitHub commits API to avoid cloning repositories with no matching recent commits.\n- By default in `--past-week`, churn is filtered to commits authored by the authenticated GitHub username.\n- Use `--all-authors` to disable author filtering, or `--author \u003cusername\u003e` to override.\n- Markup/config languages are excluded by default; use `--include-markup-langs` to opt in.\n- Clone cache is enabled by default; use `--cache-dir` to control location or `--no-cache` to disable.\n- Use `--include-repo-composition` to add full-repository composition (`repoComposition`) alongside churn results (`weeklyChurn`).\n- Continues when a repo fails and records skipped repositories in output metadata.\n\n## Token scopes\n\nFor private repos, use a token with `repo` scope. For public-only, `public_repo` is enough.\n\n## Testing\n\n```bash\npnpm test\n```\n\n## Notes\n\nGitHub’s API reports language byte totals per repository, not per-user LOC. Per-user attribution requires cloning and analyzing repositories locally.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaadjs%2Fgh-stats","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsaadjs%2Fgh-stats","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaadjs%2Fgh-stats/lists"}