Skip to content
Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

400 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GitHub Star Tracker

A GitHub Action that tracks star counts across all your repositories on a schedule, generates visual reports with charts and badges, and sends notifications when changes are detected.

CI Codecov License: AGPL-3.0 Product Hunt

Documentation · Getting Started · Configuration · Examples · Troubleshooting

Important

Coming from Star History, Starchart.cc or similar? You're in the right place.

GitHub announced that access to the stargazers API is being restricted to repository admins and collaborators. Tools that chart stars for repositories they don't own will start receiving empty responses or 403 errors.

GitHub Star Tracker is not affected. It runs inside your workflow, with your token, against your repositories: exactly the access GitHub is keeping. Star history charts, stargazer tracking, forecasts and badges keep working as always.


Table of Contents


What You Get

Every run, Star Tracker commits these artifacts to a dedicated data branch:

  • Animated SVG charts: star history, per-repo trends, top repos comparison, and growth forecasts - with automatic dark/light mode support:

    Star History Top Repositories Growth Forecast
  • Shields.io-style badge: embeddable star count that updates automatically:

    Stars
  • Markdown & HTML reports: summary tables, delta indicators, new/removed repos, stargazer details, and forecast tables.

  • CSV & JSON data: machine-readable exports for dashboards, spreadsheets, or downstream pipelines.


Features

  • 📈 Animated SVG charts: Star history, per-repo trends, comparisons, and growth forecasts
  • 🌙 Dark/light mode: SVG charts auto-adapt to the viewer's color scheme via prefers-color-scheme
  • 📷 Historical snapshots: Configurable retention (default: 52 runs) with JSON persistence
  • 🔍 Smart filtering: By visibility, ownership, min stars, regex exclusions, archived, forks
  • 👥 Stargazer tracking: See who starred your repos with avatars and dates
  • 📬 Email notifications: Built-in SMTP with fixed or adaptive thresholds
  • 🏢 GitHub Enterprise: GHES support, auto-detected or explicit API URL
  • 🌐 Multi-language: English, Spanish, Catalan, Italian
  • 📊 CSV export: Machine-readable output for data pipelines
  • 🧩 Action outputs: total-stars, new-stars, lost-stars, should-notify, notification-sent, new-stargazers (and much more) for workflow chaining
  • 🛡️ Zero runtime deps: Bundled TypeScript action, 98%+ test coverage, extensive unit test suite
  • 🔒 Future-proof: Unaffected by GitHub's 2026 stargazers API restrictions, since it uses your own credentials on your own repositories

Quick Start

1. Create a Personal Access Token

  1. Go to GitHub Settings > Tokens
  2. Generate a classic token with repo or public_repo scope
  3. Add it as a repository secret named STAR_TRACKER_TOKEN

Note

The default GITHUB_TOKEN is not sufficient. See the PAT guide for details.

2. Add the Workflow

Create .github/workflows/star-tracker.yml:

name: Track Stars

on:
  schedule:
    - cron: '0 0 * * *' # Daily at midnight
  workflow_dispatch:

permissions:
  contents: write

jobs:
  track:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
      - uses: fbuireu/github-star-tracker@v1
        with:
          github-token: ${{ secrets.STAR_TRACKER_TOKEN }}

3. Run and View

  • Manual run: Actions > Track Stars > Run workflow
  • View report: Check the star-tracker-data branch in your repository

Configuration

Set options directly in the workflow or via a YAML config file. See the Configuration guide for full details.

- uses: fbuireu/github-star-tracker@v1
  with:
    github-token: ${{ secrets.STAR_TRACKER_TOKEN }}
    visibility: 'public' # public | private | all | owned
    locale: 'es' # en | es | ca | it
    include-charts: true
    track-stargazers: true
    min-stars: '5'
    exclude-repos: 'test-repo,/^demo-.*/'
    compare-against: 'last-run' # last-run | 24h | 7d | 30d
    notification-threshold: '500' # 0 | N | auto
    notification-mode: 'gains' # net | gains
All Inputs
Input Default Description
github-token - Required. PAT with repo or public_repo scope
github-api-url - GitHub API base URL (for GHES). Auto-detected on GHES runners
config-path star-tracker.yml Path to YAML config file
visibility all public, private, all, or owned
locale en en, es, ca, or it
include-charts true Generate star trend charts
data-branch star-tracker-data Branch for tracking data
max-history 52 Max snapshots to keep
compare-against last-run Snapshot used as comparison baseline: last-run, 24h, 7d or 30d. If history is shorter than the window, the oldest stored snapshot is used and the report's date shows how far back it really goes
read-only false Run without writing to the data branch. Still fetches, reports, sets outputs and emails - it just never commits or pushes. Use it for a second workflow that shares a data branch with your tracking one
top-repos 10 Top repos in charts/forecasts
chart-line-color #dfb317 Hex color of primary chart line/fill/points (not comparison). Accepts hex with or without a leading #
chart-line-width 2.5 Stroke width (px, >0) of data lines in all charts
chart-max-points 30 Curve granularity: points across the full span (capped at 365); 0 reconstructs at weekly resolution. Not a time window (see chart-range)
chart-y-axis-side left Y-axis labels side: left or right
chart-smoothing true Smooth curve (true) or straight segments to show spikes; applies to email charts too
chart-curve monotone Curve when smoothing: monotone (no overshoot, best for stars), catmull-rom, cubic-bezier, rounded-step. Email approximates non-monotone curves
chart-show-points true Draw a marker on each data point (true) or hide them for a cleaner dense line (false)
chart-animation true Animate SVG charts (true) or render them static (false) for email/static contexts
chart-milestones true Show milestone reference lines on the main star-history chart (true) or hide them (false)
chart-begin-at-zero false Start the Y-axis at zero (true) or zoom into the data range (false)
chart-theme auto Color theme for the SVG charts: auto (follows prefers-color-scheme), light or dark
email-theme auto Color theme for the HTML email and its charts: auto (same as chart-theme), light or dark. Email charts are images, so a dark-mode reader needs this to resolve to dark
chart-custom-milestones (empty) Comma-separated star counts for the milestone reference lines, replacing the built-in defaults (e.g. 250, 750, 2500). Requires chart-milestones
chart-range all Time window plotted: 30d, 90d, 1y or all
chart-trend-line false Overlay a dashed moving-average trend line on the main chart
velocity-metrics false Add a growth-velocity section (stars/day, % growth, days to next milestone) to the report
track-stargazers false Track individual stargazers
smart-sampling false Sample stargazer pages for high-star repos (avoids rate limits)
smart-sampling-threshold 1500 Star count above which a repo is sampled
smart-sampling-pages 30 Max evenly-spaced stargazer pages per sampled repo
include-archived false Include archived repos
include-forks false Include forked repos
exclude-repos - Names or regex to exclude
only-repos - Only track these repos
only-orgs - Only track repos under these orgs/owners (name or regex)
exclude-orgs - Orgs/owners to exclude (name or regex)
min-stars 0 Min stars to track
smtp-host - SMTP hostname (enables email)
smtp-port 587 SMTP port
smtp-username - SMTP username
smtp-password - SMTP password
email-to - Recipient address
email-from localized Sender name or address; defaults to a localized sender name
send-on-no-changes false Email even with no changes
notification-threshold 0 0 (every run with changes), N (accumulated change since the last notification), or auto (adaptive)
notification-mode net How the threshold measures that change: net (absolute change, so a large drop also fires) or gains (upward movement only)

The threshold counter is measured against the star total at the last notification and only resets when a notification actually fires, so it accumulates across runs until it trips. On a data branch that has never sent a notification there is no stored baseline (treated as 0), so the first run fires immediately and then settles. If you were already running with the default notification-threshold: 0, notifications have been firing on every changed run, so the baseline already sits at your current total and raising the threshold fires nothing immediately - it waits until the total actually moves by that much.

[!IMPORTANT] notification-threshold decides when you get an email. compare-against decides what period the report body covers. They are independent: the threshold accumulates against the star total at the last notification, while the report diffs against a stored snapshot. A threshold that trips after several runs still produces a report covering only the compare-against window, so set the two to match if you want the email body to span what the threshold accumulated. notification-threshold also does not work on a read-only run, because the counter it advances lives on the data branch.

In the YAML config file, option keys may be written with either dashes or underscores - include-charts and include_charts are both accepted - so you can copy option names straight from this table without rewriting the separators.

Outputs
Output Description
total-stars Total star count
stars-changed true / false - anything changed vs. the comparison baseline (per run)
new-stars Stars gained vs. the comparison baseline. Per run, not cumulative
lost-stars Stars lost vs. the comparison baseline. Per run, not cumulative
should-notify true / false - the cumulative threshold signal, driven by notification-threshold and notification-mode (and requires an actual change)
notification-sent true / false - whether an email was actually delivered. should-notify is the decision; this is the outcome
new-stargazers New stargazers vs. the stored stargazer list, which every writing run rewrites - not driven by compare-against
report Full Markdown report
report-html HTML report (for email)
report-html-path File path to the HTML report (for large reports / custom mailers)
report-csv CSV report (for data pipelines)

To email on every N stars, use notification-threshold: 'N' with notification-mode: 'gains' and gate the step on if: steps.tracker.outputs.should-notify == 'true'. Gating on new-stars >= N would require N stars inside a single run, which on a daily schedule almost never happens.

API Reference: Complete inputs, outputs, and data formats


How It Works

---
config:
  look: handDrawn
  theme: neutral
---
flowchart TD
    trigger(["Workflow Trigger"])
    config["Parse configuration"]
    fetch["Query GitHub REST API(repositories endpoint)"]
    filter["Apply filter criteria"]
    init["Initialize orphan branch"]
    read["Deserialize previous  state snapshot"]
    compare["Compute delta metrics"]
    stargazers["Fetch stargazers (starred_at)"]
    history["Build real star history"]
    forecast["Compute growth forecast"]
    md["Markdown report"]
    json["JSON dataset"]
    csv["CSV report"]
    svg["SVG badge"]
    html["HTML digest"]
    charts["SVG charts"]
    commit["Git commit & push (data branch)"]
    setout["Export action outputs"]
    email{"SMTP configured?"}
    send["Dispatch notification"]

    trigger --> config --> fetch --> filter
    filter --> init --> read --> compare
    compare --> stargazers --> history --> forecast
    forecast --> md & json & csv & svg & html & charts
    md & json & csv & svg & html & charts --> commit --> setout --> email
    email -->|Yes| send

    style trigger fill:#e1f5ff,stroke:#01579b,stroke-width:2px
    style config fill:#fff3e0,stroke:#e65100,stroke-width:2px
    style fetch fill:#fff3e0,stroke:#e65100,stroke-width:2px
    style filter fill:#fff3e0,stroke:#e65100,stroke-width:2px
    style init fill:#f3e5f5,stroke:#4a148c,stroke-width:2px
    style read fill:#f3e5f5,stroke:#4a148c,stroke-width:2px
    style compare fill:#f3e5f5,stroke:#4a148c,stroke-width:2px
    style stargazers fill:#f3e5f5,stroke:#4a148c,stroke-width:2px
    style history fill:#f3e5f5,stroke:#4a148c,stroke-width:2px
    style forecast fill:#f3e5f5,stroke:#4a148c,stroke-width:2px
    style md fill:#e8f5e9,stroke:#1b5e20,stroke-width:2px
    style json fill:#e8f5e9,stroke:#1b5e20,stroke-width:2px
    style csv fill:#e8f5e9,stroke:#1b5e20,stroke-width:2px
    style svg fill:#e8f5e9,stroke:#1b5e20,stroke-width:2px
    style html fill:#e8f5e9,stroke:#1b5e20,stroke-width:2px
    style charts fill:#e8f5e9,stroke:#1b5e20,stroke-width:2px
    style commit fill:#fce4ec,stroke:#880e4f,stroke-width:2px
    style setout fill:#fce4ec,stroke:#880e4f,stroke-width:2px
    style email fill:#fce4ec,stroke:#880e4f,stroke-width:2px
    style send fill:#fce4ec,stroke:#880e4f,stroke-width:2px
Loading

How It Works: Full architecture and execution pipeline

How the charts read dates

The charts plot the real historical curve: every star is placed on the date it was actually given. Each stargazer carries a starred_at timestamp (GitHub's application/vnd.github.star+json media type), and the action reconstructs the cumulative star count over real time from those dates, so the timeline runs from a repo's very first star up to now, regardless of when you started running the action.

The per-run snapshots on the data branch are still kept for the report's delta tables and notifications ("how many stars changed against the comparison baseline", which compare-against selects), but the charts themselves no longer depend on them.

One caveat: GitHub caps the stargazers listing at roughly 40,000 per repo (oldest first), so for very large repos the most recent stars are unreachable. The reachable history is drawn accurately and the recent tail is bridged with a straight ramp up to the true current total, so the early curve stays accurate and the chart never goes flat at the end. Pair this with smart-sampling to keep the request cost bounded on big repos.

The line style is configurable via chart-curve (monotone by default, plus catmull-rom, cubic-bezier and rounded-step), along with theme, colors, milestones, point markers, the time window and more. See the examples gallery for a rendered comparison of every option.


Embedding in Your README

Star Badge

![Stars](https://raw.githubusercontent.com/YOUR_USER/YOUR_REPO/star-tracker-data/stars-badge.svg)

Star History Chart

![Star History](https://raw.githubusercontent.com/YOUR_USER/YOUR_REPO/star-tracker-data/charts/star-history.svg)

Tip

SVG charts automatically adapt to dark and light mode. No extra configuration needed - they use prefers-color-scheme to match the viewer's theme.

Viewing Reports: All access methods (data branch, badges, outputs, email)


Documentation

Guide Description
Getting Started Setup from token to first run
How It Works Execution flow and architecture
Configuration All options and settings
API Reference Inputs, outputs, and data formats
Examples Real-world workflow configurations
Star Trend Charts Chart types, embedding, and customization
Email Notifications Built-in SMTP and external action setup
Viewing Reports Data branch, badges, outputs, raw data
Data Management Storage, rotation, and manual management
Internationalization Multi-language support
Personal Access Token Classic and fine-grained token setup
Technical Stack Technologies and design decisions
Known Limitations Constraints and workarounds
Troubleshooting Common issues and solutions

For why the action is built the way it is — one decision per file, including the AGPL-3.0-only licence and what it asks of anyone redistributing or hosting a modified version — see the architecture decision records.

Support & Contributing

If you find this project useful, consider supporting its development:

Sponsor Buy Me A Beer


Use of AI

This project uses AI assistance primarily for documentation purposes. AI tools (GitHub Copilot, Claude) were used to:

  • Write and improve documentation (README, wiki pages)
  • Generate boilerplate code and configuration files
  • Assist with code reviews and suggestions

The core logic, architecture decisions, and implementation were developed by the maintainer. All AI-generated content has been reviewed and validated.


AGPL-3.0 © Made with 🤘🏼 by Ferran Buireu

About

⭐ GitHub Action to automatically track star count changes across repositories with visual charts, email notifications, and historical reports

Topics

Resources

Contributing

Security policy

Stars

5 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages