{"id":14032393,"url":"https://github.com/vladkens/ghstats","last_synced_at":"2026-03-08T12:37:38.170Z","repository":{"id":250358636,"uuid":"833875266","full_name":"vladkens/ghstats","owner":"vladkens","description":"🤩📈 Self-hosted dashboard for tracking GitHub repos traffic history longer than 14 days.","archived":false,"fork":false,"pushed_at":"2025-02-15T22:47:32.000Z","size":296,"stargazers_count":146,"open_issues_count":2,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-29T13:04:56.141Z","etag":null,"topics":["dashboard","github","github-api","github-tracker","github-traffic","rust","self-hosted","stargazers"],"latest_commit_sha":null,"homepage":"","language":"Rust","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/vladkens.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"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},"funding":{"github":"vladkens","buy_me_a_coffee":"vladkens"}},"created_at":"2024-07-26T00:19:57.000Z","updated_at":"2025-03-27T00:41:57.000Z","dependencies_parsed_at":"2024-08-28T21:52:38.735Z","dependency_job_id":"85b55fc3-6659-46db-8a1e-22765894f564","html_url":"https://github.com/vladkens/ghstats","commit_stats":null,"previous_names":["vladkens/ghstats"],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vladkens%2Fghstats","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vladkens%2Fghstats/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vladkens%2Fghstats/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vladkens%2Fghstats/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vladkens","download_url":"https://codeload.github.com/vladkens/ghstats/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247345850,"owners_count":20924102,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["dashboard","github","github-api","github-tracker","github-traffic","rust","self-hosted","stargazers"],"created_at":"2024-08-12T00:01:37.162Z","updated_at":"2026-03-08T12:37:33.131Z","avatar_url":"https://github.com/vladkens.png","language":"Rust","funding_links":["https://github.com/sponsors/vladkens","https://buymeacoffee.com/vladkens"],"categories":["Software","Rust"],"sub_categories":["Analytics"],"readme":"# ghstats\n\n\u003cdiv align=\"center\"\u003e\n\nSelf-hosted dashboard for tracking GitHub repos traffic history longer than 14 days.\n\n[\u003cimg src=\"https://badges.ws/github/release/vladkens/ghstats\" alt=\"version\" /\u003e](https://github.com/vladkens/ghstats/releases)\n[\u003cimg src=\"https://badges.ws/github/license/vladkens/ghstats\" alt=\"license\" /\u003e](https://github.com/vladkens/ghstats/blob/main/LICENSE)\n[\u003cimg src=\"https://badges.ws/badge/-/buy%20me%20a%20coffee/ff813f?icon=buymeacoffee\u0026label\" alt=\"donate\" /\u003e](https://buymeacoffee.com/vladkens)\n\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/vladkens/ghstats/blob/assets/preview.png?raw=true\" alt=\"preview\" /\u003e\n\u003c/div\u003e\n\n## 🌟 Features\n\n- Collect \u0026 store traffic metrics for all your repos\n- List of repos and informative dashboard for each\n- No React / Next / Postgres etc, just single and small Docker image (20MB) \u0026 SQLite\n\n## 🚀 Usage\n\n```sh\ndocker run -d --env-file .env -p 8080:8080 -v ./data:/app/data --name ghstats ghcr.io/vladkens/ghstats:latest\n```\n\nOr Docker Compose:\n\n```yaml\nservices:\n  ghstats:\n    image: ghcr.io/vladkens/ghstats:latest\n    container_name: ghstats\n    restart: always\n    environment:\n      - GITHUB_TOKEN=???\n    env_file: .env # or with .env file\n    ports:\n      - 8080:8080\n    volumes:\n      - ./data:/app/data\n```\n\n### Github token generation\n\n`ghstats` needs Github Token to collect traffic data from API. Token can be obtained with following steps:\n\n1. Go to https://github.com/settings/tokens\n2. Generate new token \u003e Generate new token (classic)\n3. Enter name, e.g.: `ghstats`. Scopes: `public_repo`\n4. Click genereate token \u0026 copy it\n5. Save token to `.env` file with name `GITHUB_TOKEN=ghp_XXX`\n\nNote: If you want to access private repos too, choose full `repo` scope and set `GHS_INCLUDE_PRIVATE=true` to env.\n\n## How it works?\n\nEvery hour `ghstats` loads the list of public repositories and their statistics, and saves the data in SQLite. If at the first startup there is no repositories in the database, synchronization will happen immediately, if `ghstats` is restarted again, synchronization will be performed according to the scheduler. Data is stored per day, re-fetching data for the current day will update existing records in the database.\n\nAll public repositories that can be accessed are saved. If you need more detailed configuration – open PR please.\n\n## Configuration\n\n### Host \u0026 Port\n\nYou can to change default host / port app will run on with `HOST` (default `0.0.0.0`) and `PORT` (default `8080`) environment variables.\n\n### Custom links\n\nIf you plan to display your stats publicly, there is an option to add custom links to the header via environment variables, e.g.:\n\n```sh\nGHS_CUSTOM_LINKS=\"Blog|https://medium.com/@vladkens,Github|https://github.com/vladkens,Buy me a coffee|https://buymeacoffee.com/vladkens\"\n```\n\n### Filter repos\n\nYou can filter repos for display (and data collection). You can select a specific org/user or a specific list of repositories. This is configured via the `GHS_FILTER` environment variable. You can use negation in the rules to remove a specific repo or org/user using the `!` symbol. By default, all repos are shown.\n\n_Note: Statistics on previously downloaded repos remain in database, but they are hidden from display._\n\nUsage examples:\n\n```sh\nGHS_FILTER=vladkens/macmon,vladkens/ghstats # show only this two repo\nGHS_FILTER=vladkens/*,foo-org/bar # show all vladkens repos and one repo from `foo-org`\nGHS_FILTER=vladkens/*,!vladkens/apigen-ts # show all vladkens repos except `apigen-ts`\nGHS_FILTER=*,!vladkens/apigen-ts,!foo-org/bar # show all repos expect two\n\nGHS_FILTER=*,!fork # show all repos expect forks\nGHS_FILTER=vladkens/*,!fork # show all vladkens repos expect forks\nGHS_FILTER=*,vladkens/some-fork,!fork # show all repos expect forks and keep `some-fork`\n\nGHS_FILTER=*,!archived # show all repos expect archived\n```\n\nFiltering rules:\n\n- If no filter provided all repos will be shown (implicitly `*`)\n- There are two kind of rules: direct (`foo/bar`, `foo/*`) and meta (`*`, `!fork`, `!archived`)\n- Direct rule can be wildcard (`foo/*` – include all repos of `foo` org / user)\n- Direct rules are applied first, then meta\n- If no direct rules specified, all repos included by default (implicitly `*`)\n- If at least one direct rule – all repos excluded by default (pass `*` explicitly to include all)\n- Meta-exclusion rules are: `!fork`, `!archived`\n- Wildcard rules do not work with meta-exclusion rules\n\n### API endpoint\n\nYou have the ability to get collected data by `ghstats` via API. At the moment there is only one method available to get all repos list – if you need other data – open PR, please. `GHS_API_TOKEN` environment variable must be set for the API to work. All API calls if protected by `x-api-token` header, which should be same with `GHS_API_TOKEN` variable. CORS is enabled for all hosts, so you can access API from personal pages.\n\n#### Endpoints\n\n`/api/repos` – will return list of all repos and overall metrics. Data returted in JSON format. Usage example:\n\n```sh\ncurl -H \"x-api-token:1234\" http://127.0.0.1:8080/api/repos\n```\n\n```jsonc\n{\n  \"total_count\": 20,\n  \"total_stars\": 1000,\n  \"total_forks\": 200,\n  \"total_views\": 20000,\n  \"total_clones\": 500,\n  \"items\": [\n    {\n      \"id\": 833875266,\n      \"name\": \"vladkens/ghstats\",\n      \"description\": \"🤩📈 Self-hosted dashboard for tracking GitHub repos traffic history longer than 14 days.\",\n      \"date\": \"2024-09-08T00:00:00Z\",\n      \"stars\": 110,\n      \"forks\": 1,\n      \"watchers\": 110,\n      \"issues\": 5,\n      \"prs\": 1,\n      \"clones_count\": 90,\n      \"clones_uniques\": 45,\n      \"views_count\": 1726,\n      \"views_uniques\": 659\n    }\n    // ...\n  ]\n}\n```\n\n## 🤝 Contributing\n\nAll contributions are welcome! Feel free to open an issue or submit a pull request.\n\n## 🔍 See also\n\n- [repohistory](https://github.com/repohistory/repohistory) – NodeJS application as a service.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvladkens%2Fghstats","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvladkens%2Fghstats","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvladkens%2Fghstats/lists"}