<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[GitHubCard]]></title><description><![CDATA[GitHubCard]]></description><link>https://githubcard.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Tue, 27 Oct 2026 06:40:56 GMT</lastBuildDate><atom:link href="https://githubcard.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[GitHub Star History Not Working? Use the New /stargazers/history Endpoint (2026)]]></title><description><![CDATA[The stargazers API now returns 401/403 for most repos. Here's how to get weekly and daily star counts without it.]]></description><link>https://githubcard.hashnode.dev/github-star-history-not-working-use-the-new-stargazers-history-endpoint-2026</link><guid isPermaLink="true">https://githubcard.hashnode.dev/github-star-history-not-working-use-the-new-stargazers-history-endpoint-2026</guid><category><![CDATA[GitHub]]></category><category><![CDATA[api]]></category><category><![CDATA[Open Source]]></category><category><![CDATA[Python]]></category><dc:creator><![CDATA[Colin]]></dc:creator><pubDate>Tue, 20 Oct 2026 01:37:02 GMT</pubDate><content:encoded><![CDATA[<p>TL;DR:</p>
<ul>
<li>Since July 2026, <code>GET /repos/{owner}/{repo}/stargazers</code> only works for repo admins and collaborators. A token doesn't help if you're neither.</li>
<li>If you only need the growth curve, GitHub shipped <code>GET /repos/{owner}/{repo}/stargazers/history</code> on 2026-09-04. It returns star counts per week and per day, with no user identities.</li>
<li>For public repos it returned <code>200</code> without a token when I tested it (unauthenticated limit: 60 requests/hour).</li>
<li>Last checked: 2026-10-19.</li>
</ul>
<p>Your README's star history chart went blank one day, and <code>curl</code> gives you a <code>401</code>. I build a tool that draws GitHub star charts, so I ran straight into this change. These are my notes.</p>
<h2>Symptoms and what they mean</h2>
<table>
<thead>
<tr>
<th>Symptom</th>
<th>Cause</th>
<th>What to do</th>
</tr>
</thead>
<tbody><tr>
<td><code>GET /stargazers</code> returns <code>401 Requires authentication</code></td>
<td>The July 2026 restriction. This is what I got calling it without a token</td>
<td>Switch to <code>/stargazers/history</code></td>
</tr>
<tr>
<td><code>GET /stargazers</code> returns <code>403</code> or an empty response</td>
<td>Same restriction. GitHub's wording is "empty responses or a 403"</td>
<td>Only admins and collaborators can read it. For a growth curve, use <code>/stargazers/history</code></td>
</tr>
<tr>
<td>Star history image in a README is blank or broken</td>
<td>Third-party services can no longer read the stargazer list of repos they don't own</td>
<td>See "Putting a star chart in your README" below</td>
</tr>
<tr>
<td><code>/stargazers/history</code> returns <code>422 Pagination is limited to 100 pages.</code></td>
<td><code>page</code> is above 100</td>
<td>Keep <code>page</code> between 1 and 100</td>
</tr>
<tr>
<td><code>/stargazers/history</code> returns <code>200</code> with <code>[]</code></td>
<td>You've gone past the week the repo was created</td>
<td>Stop paginating there</td>
</tr>
<tr>
<td><code>/stargazers/history</code> returns <code>404</code></td>
<td>The repo doesn't exist (tested)</td>
<td>Check <code>owner/repo</code></td>
</tr>
</tbody></table>
<p><strong>Logging in doesn't fix it.</strong> The rule is "admins and collaborators only", not "authentication required", so a token still won't list stargazers for someone else's repo.</p>
<h2>What changed</h2>
<table>
<thead>
<tr>
<th>Date</th>
<th>Event</th>
</tr>
</thead>
<tbody><tr>
<td>2026-06-30</td>
<td>GitHub announced the access restrictions (changelog)</td>
</tr>
<tr>
<td>July 2026</td>
<td>Restrictions took effect. GitHub only gives the month</td>
</tr>
<tr>
<td>2026-09-04</td>
<td>New <code>/stargazers/history</code> endpoint released</td>
</tr>
<tr>
<td>2026-10-14</td>
<td>Engineering blog post on how it was built</td>
</tr>
</tbody></table>
<p>The affected endpoints are <code>/repos/{owner}/{repo}/stargazers</code> (who starred) and <code>/repos/{owner}/{repo}/subscribers</code> (watchers). <code>/users/{username}/subscriptions</code> was deprecated.</p>
<p>The reason is spam. Public stargazer lists were being scraped in bulk and used as target lists for spam and phishing.</p>
<p>But tools like star-history.com built their charts by stacking up the timestamps in that list, so they broke too.</p>
<h2>/stargazers/history: weekly star counts, no identities</h2>
<p><code>GET /repos/{owner}/{repo}/stargazers/history</code> returns star counts grouped by calendar week, without saying who starred. Each week includes 7 daily counts, and one request returns up to 30 weeks.</p>
<table>
<thead>
<tr>
<th>Field</th>
<th>Value</th>
</tr>
</thead>
<tbody><tr>
<td><code>per_page</code></td>
<td>Counted in weeks. Default 30, max 30 (passing 31 was treated as 30)</td>
</tr>
<tr>
<td><code>page</code></td>
<td>Default 1, max 100. Higher means older</td>
</tr>
<tr>
<td>Order</td>
<td>Newest first. Chaining pages gives a continuous series back to the creation week</td>
</tr>
<tr>
<td>Weeks with no stars</td>
<td>Returned as 0</td>
</tr>
<tr>
<td>Status codes</td>
<td>200, 422 (validation failed, or "endpoint has been spammed")</td>
</tr>
<tr>
<td>Caching</td>
<td><code>cache-control: public, max-age=60, s-maxage=60</code>, with an ETag</td>
</tr>
</tbody></table>
<p>Here's an unauthenticated call against octocat/Hello-World on 2026-10-19:</p>
<pre><code class="language-bash">$ curl -i -H "Accept: application/vnd.github+json" \
    -H "X-GitHub-Api-Version: 2026-03-10" \
    "https://api.github.com/repos/octocat/Hello-World/stargazers/history?per_page=2"
HTTP/2 200
link: &lt;…/stargazers/history?per_page=2&amp;page=2&gt;; rel="next", &lt;…/stargazers/history?per_page=2&amp;page=100&gt;; rel="last"
x-github-api-version-selected: 2026-03-10

[{"week":1792281600,"total":7,"days":[7,0,0,0,0,0,0]},
 {"week":1791676800,"total":52,"days":[32,3,4,5,5,1,2]}]
</code></pre>
<ul>
<li><code>week</code>: start of the week (Unix seconds)</li>
<li><code>days</code>: daily counts for that week, 7 values starting on Sunday</li>
<li><code>total</code>: the week's sum</li>
</ul>
<p>So you get daily resolution, not just weekly. The shape matches <code>/stats/commit_activity</code>.</p>
<p>It also worked without <code>X-GitHub-Api-Version</code> (GitHub then picks <code>2022-11-28</code>), but I'd send the header anyway.</p>
<h2>Auth and rate limits: 60/hour without a token</h2>
<p>For public repos I got <code>200</code> without a token. The headers said <code>x-ratelimit-limit: 60</code> and <code>x-ratelimit-resource: core</code>, the same 60 requests/hour as the rest of the unauthenticated REST API. The docs don't explicitly say "no auth required", so treat this as what I saw, not a promise.</p>
<p>The endpoint page doesn't list the authenticated limit or which fine-grained token permission it needs, and I haven't tested those yet, so I won't guess.</p>
<p>Re-requesting with the ETag gives a <code>304</code>. But GitHub's best-practices page says a 304 only skips the rate limit when the request has an <code>Authorization</code> header. Without a token, assume it still counts.</p>
<h2>Getting the full history: paginate until you get []</h2>
<p>Start at <code>page=1</code> and keep going until the response is <code>[]</code>. For octocat/Hello-World (created in 2011), data ran through page 28. Page 29 returned <code>[]</code> and page 101 returned <code>422</code>.</p>
<pre><code class="language-bash">$ curl -s "https://api.github.com/repos/octocat/Hello-World/stargazers/history?page=29"
[]
$ curl -s "https://api.github.com/repos/octocat/Hello-World/stargazers/history?page=101"
{"message":"Pagination is limited to 100 pages.", … "status":"422"}
</code></pre>
<p>The number of requests is roughly "weeks the repo has existed ÷ 30". It doesn't depend on how many stars the repo has.</p>
<p>Watch out: with <code>per_page</code> below 30, the <code>rel="last"</code> link in the <code>Link</code> header points at <code>page=100</code>. That's the page cap, not the real last page. With <code>per_page=30</code> it pointed at the real last page (28 for Hello-World).</p>
<h2>A cumulative star CSV in plain Python</h2>
<p>Standard library only. It fetches every page, flips them to oldest first, and keeps a running total.</p>
<pre><code class="language-python"># star_history.py: build a cumulative star CSV from GitHub's /stargazers/history
import json, sys, urllib.request
from datetime import datetime, timezone

repo = sys.argv[1]  # e.g. octocat/Hello-World
weeks, page, calls = [], 1, 0
while page &lt;= 100:  # page is capped at 100
    url = f"https://api.github.com/repos/{repo}/stargazers/history?per_page=30&amp;page={page}"
    req = urllib.request.Request(url, headers={
        "Accept": "application/vnd.github+json",
        "X-GitHub-Api-Version": "2026-03-10",
    })
    with urllib.request.urlopen(req) as res:
        batch = json.load(res)
    calls += 1
    if not batch:  # pages older than the creation week return []
        break
    weeks.extend(batch)
    page += 1

weeks.reverse()  # newest-first -&gt; oldest-first
total = 0
print("week_start,new_stars,cumulative")
for w in weeks:
    total += w["total"]
    day = datetime.fromtimestamp(w["week"], tz=timezone.utc).date()
    print(f"{day},{w['total']},{total}")
print(f"# {repo}: {len(weeks)} weeks, {calls} requests, total {total}", file=sys.stderr)
</code></pre>
<pre><code class="language-bash">$ python3 star_history.py octocat/Hello-World &gt; hello.csv
# octocat/Hello-World: 822 weeks, 29 requests, total 3857
$ head -3 hello.csv
week_start,new_stars,cumulative
2011-01-23,62,62
2011-01-30,1,63
</code></pre>
<p>On 2026-10-19 that pulled 822 weeks in 29 requests. The last request is just the <code>[]</code> check.</p>
<p>One thing I can't explain yet: at 2026-10-18 17:29 UTC, <code>GET /repos/octocat/Hello-World/stargazers/count</code> returned <code>{"count": 3858}</code> and <code>stargazers_count</code> on the repo said <code>3858</code> too. The history added up to <code>3857</code>, and rerunning the script right after still gave <code>3857</code>. So it's off by one, and I don't know why.</p>
<p>Feed the CSV to any chart library and you have a cumulative chart. If you only care about recent growth, <code>per_page=1</code> is a single request that returns this week's daily counts:</p>
<pre><code class="language-bash">$ curl -s "https://api.github.com/repos/octocat/Hello-World/stargazers/history?per_page=1"
[{"week":1792281600,"total":7,"days":[7,0,0,0,0,0,0]}]
</code></pre>
<h2>Caveats</h2>
<ol>
<li>Unstars disappear. When someone removes a star, the record is gone. The cumulative chart shows when <em>current</em> stargazers starred, so it can come out lower than numbers you saw in the past, and it can't show a drop.</li>
<li>Week and day boundaries may not be UTC. The docs say "Week and day boundaries are not guaranteed to align with UTC." My script prints UTC dates, so a date can look one day off.</li>
<li>No date range filter. You walk back from the newest page.</li>
<li>No identities. You can't build "a famous dev starred your repo" features on this.</li>
<li>A 422 can also mean "endpoint has been spammed". The threshold isn't public.</li>
<li>Weeks with a huge spike of stars can be slow. GitHub calls this a remaining scaling issue.</li>
</ol>
<h2>Why 2,511 requests became 24</h2>
<p>GitHub's engineering post uses react/react (about 251k stars) as the example: about 2,511 requests for full history on the old API, about 24 on the new one.</p>
<p>Their first attempt aggregated everything up front and paginated with <code>OFFSET/LIMIT</code>. That got requests down to 24, but the database still scanned about 6 million rows. Small responses don't make a query cheap.</p>
<p>The version that shipped turns page numbers into indexed date ranges, so it filters by period first and aggregates second. That scans about 251k rows, roughly one read per star.</p>
<h2>Putting a star chart in your README</h2>
<p>A few options:</p>
<ul>
<li>Generate an SVG with GitHub Actions. Run the script above on a schedule and commit the SVG. No third-party dependency, so it's the most stable, but you maintain the workflow.</li>
<li>star-history.com, a popular site for star charts. GitHub's engineering post quotes its maintainer, Tianzhou Chen. I haven't confirmed whether it uses the new endpoint.</li>
<li>GitHubCard, the profile and repo card tool I'm building. I switched it to this endpoint, so you can now add a star history chart for any public repo, including ones you don't own, without signing in (saving and publishing still need a login). How it works is on <a href="https://githubcard.com/blog/github-star-history-privacy-safe-api?lang=en&amp;utm_source=hashnode&amp;utm_medium=article&amp;utm_campaign=star-history-api">our product blog</a>.</li>
</ul>
<p>If you just want one chart, star-history.com is probably enough. If you'd rather not depend on an outside service, use Actions.</p>
<h2>Wrap-up</h2>
<p>GitHub stopped publishing <em>who</em> starred a repo. <em>When and how many</em> is still available through the new endpoint. For a growth curve, paginating <code>/stargazers/history</code> is enough. Just keep in mind that unstars aren't counted and that week and day boundaries aren't guaranteed to be UTC.</p>
<p>I'll update this post once I've tested the authenticated behavior.</p>
<h2>References</h2>
<ol>
<li><a href="https://github.blog/changelog/2026-09-04-new-api-endpoint-provides-privacy-safe-star-history-data/">New API endpoint provides privacy-safe star history data</a> (GitHub Changelog, 2026-09-04)</li>
<li><a href="https://github.blog/engineering/architecture-optimization/from-2500-requests-to-24-rebuilding-star-history-without-the-stargazers/">From 2,500 requests to 24: Rebuilding star history without the stargazers</a> (GitHub Blog, 2026-10-14)</li>
<li><a href="https://docs.github.com/en/rest/activity/starring">REST API endpoints for starring: Get repository star history</a> (GitHub Docs)</li>
<li><a href="https://github.blog/changelog/2026-06-30-upcoming-access-restrictions-to-public-api-endpoints-and-ui-views/">Upcoming access restrictions to public API endpoints and UI views</a> (GitHub Changelog, 2026-06-30)</li>
<li><a href="https://docs.github.com/en/rest/using-the-rest-api/best-practices-for-using-the-rest-api">Best practices for using the REST API</a> (GitHub Docs)</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[GitHub Readme Stats Not Working? How to Fix 503, Rate Limits, 403 and Broken Images]]></title><description><![CDATA[You open your GitHub profile and the stats card is gone. All that's left is a broken image icon, or a grey "Something went wrong" box. Nothing changed in…]]></description><link>https://githubcard.hashnode.dev/github-readme-stats-not-working-how-to-fix-503-rate-limits-403-and-broken-images</link><guid isPermaLink="true">https://githubcard.hashnode.dev/github-readme-stats-not-working-how-to-fix-503-rate-limits-403-and-broken-images</guid><category><![CDATA[GitHub]]></category><category><![CDATA[Open Source]]></category><category><![CDATA[webdev]]></category><category><![CDATA[Tutorial]]></category><dc:creator><![CDATA[Colin]]></dc:creator><pubDate>Wed, 14 Oct 2026 15:01:48 GMT</pubDate><content:encoded><![CDATA[<p>You open your GitHub profile and the stats card is gone. All that's left is a broken image icon, or a grey "Something went wrong" box. Nothing changed in your README, so what broke?</p>
<p>Almost always, the problem is the public service that draws the card, not your Markdown. Below is how I narrow it down, and three fixes that actually last.</p>
<p><em>Last verified: Oct 14, 2026.</em></p>
<h2>TL;DR</h2>
<table>
<thead>
<tr>
<th>Symptom</th>
<th>Likely cause</th>
<th>Fastest fix</th>
</tr>
</thead>
<tbody><tr>
<td><code>503</code> / <code>DEPLOYMENT_PAUSED</code></td>
<td>Public github-readme-stats instance paused</td>
<td>GitHub Actions or self-host</td>
</tr>
<tr>
<td>"Something went wrong" card</td>
<td>GitHub API rate limit or a fetch error</td>
<td>Your own token (Actions / self-host)</td>
</tr>
<tr>
<td><code>403 Forbidden</code> on streak card</td>
<td>Public streak endpoint blocking requests</td>
<td>Streak Stats GitHub Action</td>
</tr>
<tr>
<td>Broken image icon, no error</td>
<td>Slow response or a cached failure behind GitHub's image proxy</td>
<td>Static SVG in your repo</td>
</tr>
<tr>
<td>Card shows the wrong data</td>
<td>Typo, wrong username, cache</td>
<td>Check the URL and wait out the cache</td>
</tr>
</tbody></table>
<h2>Step 1: Is it you or the service?</h2>
<p>Copy the image URL out of your README and open it straight in your browser. Or check the headers:</p>
<pre><code class="language-bash">curl -I "https://github-readme-stats.vercel.app/api?username=YOUR_USERNAME"
curl -I "https://streak-stats.demolab.com/?user=YOUR_USERNAME"
</code></pre>
<ul>
<li><strong>200 with <code>image/svg+xml</code></strong> and a normal card: the service is fine. The problem is in your README (see Step 6) or a stale cached copy on GitHub.</li>
<li><strong>200 but the SVG says "Something went wrong"</strong>: the service is up but couldn't fetch your data. This is usually a rate limit.</li>
<li><strong>503</strong>: the instance itself is down or paused.</li>
<li><strong>403</strong>: the endpoint is refusing the request.</li>
</ul>
<p>When I checked on Oct 14, both public endpoints returned 200. They work most days, but they go down every so often, so "it works right now" doesn't mean it'll still work tomorrow.</p>
<h2>Step 2: Know why the public instances break</h2>
<p><strong>503 DEPLOYMENT_PAUSED.</strong> In <a href="https://github.com/anuraghazra/github-readme-stats/issues/3851">#3851</a> ("Public deployment paused"), the maintainers explain that Vercel's sponsorship ended. They point people to GitHub Actions or self-hosting instead. <a href="https://github.com/anuraghazra/github-readme-stats/issues/4737">#4737</a> and <a href="https://github.com/anuraghazra/github-readme-stats/issues/4798">#4798</a> ("not working again ?") are both still open. The repo README now also says the project is no longer maintained and recommends its successor, <a href="https://github.com/stats-organization/github-stats-extended">GitHub Stats Extended</a>.</p>
<p><strong>Rate limits.</strong> The README says the public instance is "best-effort and can be unreliable due to rate limits and traffic spikes." Thousands of profiles share one pool of GitHub API requests. When that pool runs out, you get the error card.</p>
<p><strong>403 on Streak Stats.</strong> In <a href="https://github.com/DenverCoder1/github-readme-streak-stats/issues/872">streak #872</a>, users reported every public streak endpoint returning 403. That issue is closed now, but it can happen again.</p>
<p><strong>Broken image, no error.</strong> GitHub doesn't load README images straight from the source. It serves them through its own image proxy (camo). If the card service is slow, the image may just not appear. Users have reported this in <a href="https://github.com/DenverCoder1/github-readme-streak-stats/issues/754">streak #754</a> and <a href="https://github.com/DenverCoder1/github-readme-streak-stats/issues/792">#792</a>.</p>
<h2>Step 3 (recommended): Generate the SVGs with GitHub Actions</h2>
<p>This is the fix that holds up best. A workflow builds the cards on a schedule and commits them to your profile repo. Your README then points at a file in your own repo, with no outside service in the way.</p>
<p><strong>Stats and top languages card.</strong> Save this as <code>.github/workflows/grs.yml</code> in your <code>USERNAME/USERNAME</code> repo. It's adapted from the <a href="https://github.com/stats-organization/github-readme-stats-action">action's README</a>:</p>
<pre><code class="language-yaml">name: Update README cards
on:
  schedule:
    - cron: "0 0 * * *"
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v6
      - uses: stats-organization/github-readme-stats-action@v2
        with:
          card: stats
          options: username=${{ github.repository_owner }}&amp;show_icons=true
          path: profile/stats.svg
          token: ${{ secrets.GITHUB_TOKEN }}
      - uses: stats-organization/github-readme-stats-action@v2
        with:
          card: top-langs
          options: username=${{ github.repository_owner }}&amp;layout=compact
          path: profile/top-langs.svg
          token: ${{ secrets.GITHUB_TOKEN }}
      - uses: stats-organization/github-readme-stats-action@v2
        with:
          card: stats
          options: username=${{ github.repository_owner }}&amp;show_icons=true&amp;theme=dark
          path: profile/stats-dark.svg
          token: ${{ secrets.GITHUB_TOKEN }}
      - name: Commit cards
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git add profile/*.svg
          git commit -m "Update README cards" || exit 0
          git push
</code></pre>
<p>Then in your README:</p>
<pre><code class="language-markdown">![Stats](./profile/stats.svg)
![Top Languages](./profile/top-langs.svg)
</code></pre>
<p>To include private repo stats, create a PAT with the <code>repo</code> and <code>read:user</code> scopes. Store it as a repository secret and use it in place of <code>GITHUB_TOKEN</code>. Never paste the token into the YAML.</p>
<p><strong>Streak card.</strong> Add <code>.github/workflows/streak-stats.yml</code>, following the <a href="https://github.com/DenverCoder1/github-readme-streak-stats">Streak Stats README</a>:</p>
<pre><code class="language-yaml">      - name: Generate streak stats
        uses: DenverCoder1/github-readme-streak-stats@v1
        with:
          options: user=${{ github.repository_owner }}&amp;theme=default&amp;disable_animations=true
          path: profile/streak.svg
          token: ${{ secrets.STREAK_STATS_TOKEN }}
</code></pre>
<p>(Use the same checkout and commit steps as above.) The <code>token</code> line is only needed for private contributions. The README says to use a PAT with the <code>repo</code> scope, stored as a secret.</p>
<p>The catch: the cards only update when the workflow runs, once a day here. For a profile README, that's usually fine.</p>
<h2>Step 4: Self-host on Vercel</h2>
<p>If you want cards that update live, deploy your own instance:</p>
<ol>
<li>Fork the repo. The original README still has a Vercel guide, and GitHub Stats Extended has its own <a href="https://github-stats-extended.vercel.app/frontend/docs/deploy/#self-hosted-on-vercel">deploy docs</a>.</li>
<li>Import the fork into Vercel.</li>
<li>Create a GitHub PAT and add it as an environment variable named <code>PAT_1</code>.</li>
<li>Deploy, then <strong>swap the domain in your README</strong>:</li>
</ol>
<pre><code class="language-markdown">![Stats](https://YOUR-APP.vercel.app/api?username=YOUR_USERNAME&amp;cache_seconds=21600)
</code></pre>
<p>That last step trips people up. <a href="https://github.com/anuraghazra/github-readme-stats/issues/4747">#4747</a> covers cases where a self-hosted fork still looked broken because the README still pointed at the public URL. Check the URL.</p>
<p>On caching: <code>cache_seconds</code> takes values from 21600 to 86400, and the default is 21600. On your own instance, you can set the <code>CACHE_SECONDS</code> environment variable instead. On Vercel's free plan, keep in mind that your own usage counts against your own limits.</p>
<h2>Step 5: Top languages card looks wrong</h2>
<p>Two things come up a lot. The card only looks at your first 100 repos, and by default it ranks languages by byte count. One big Jupyter notebook can push everything else off the card.</p>
<pre><code class="language-markdown">![Top Langs](https://YOUR-APP.vercel.app/api/top-langs/?username=YOUR_USERNAME&amp;hide=jupyter%20notebook&amp;exclude_repo=old-fork&amp;size_weight=0.5&amp;count_weight=0.5)
</code></pre>
<p><code>size_weight=0.5&amp;count_weight=0.5</code> is the combination the README recommends. It weighs bytes and repo count together. To stop GitHub from counting notebooks at all, add a <code>.gitattributes</code> file to that repo:</p>
<pre><code>*.ipynb linguist-vendored
</code></pre>
<h2>Step 6: The boring causes</h2>
<p>Before you change anything else, check these:</p>
<ul>
<li>A typo in the username, or a stray <code>\&amp;</code> copied from a doc.</li>
<li><code>user=</code> vs <code>username=</code>. Streak Stats uses <code>user</code>, github-readme-stats uses <code>username</code>.</li>
<li>A renamed account.</li>
<li>A cached old version. Wait for the cache to expire before you assume it's broken.</li>
</ul>
<p>For dark/light mode, use the light and dark SVGs the workflow writes above:</p>
<pre><code class="language-html">&lt;picture&gt;
  &lt;source media="(prefers-color-scheme: dark)" srcset="./profile/stats-dark.svg" /&gt;
  &lt;img src="./profile/stats.svg" alt="GitHub stats" /&gt;
&lt;/picture&gt;
</code></pre>
<h2>Alternatives</h2>
<p>If you'd rather not maintain a workflow at all, there are a few options. <a href="https://github.com/stats-organization/github-stats-extended">GitHub Stats Extended</a> is the maintained successor and has its own public instance. The two GitHub Actions above are the most robust free option. Community-run public instances exist too, but they're third-party and nobody promises they'll stay up.</p>
<p>Full disclosure: I work on GitHubCard. <a href="https://githubcard.com">GitHubCard</a> is a hosted card editor: you design stats, top languages, streak and other widgets as one card, then embed it with a single line:</p>
<pre><code class="language-markdown">![GitHub profile card](https://githubcard.com/YOUR_USERNAME.svg)
</code></pre>
<p>It's a hosted service too, so the same logic applies: if the card has to be up 100% of the time, a static SVG committed by an Action is still the safest choice.</p>
<h2>Sources (accessed Oct 14, 2026)</h2>
<ul>
<li>github-readme-stats README and issues <a href="https://github.com/anuraghazra/github-readme-stats/issues/3851">#3851</a>, <a href="https://github.com/anuraghazra/github-readme-stats/issues/4737">#4737</a>, <a href="https://github.com/anuraghazra/github-readme-stats/issues/4747">#4747</a>, <a href="https://github.com/anuraghazra/github-readme-stats/issues/4798">#4798</a></li>
<li><a href="https://github.com/stats-organization/github-readme-stats-action">stats-organization/github-readme-stats-action</a></li>
<li><a href="https://github.com/DenverCoder1/github-readme-streak-stats">DenverCoder1/github-readme-streak-stats</a>, issues <a href="https://github.com/DenverCoder1/github-readme-streak-stats/issues/754">#754</a>, <a href="https://github.com/DenverCoder1/github-readme-streak-stats/issues/792">#792</a>, <a href="https://github.com/DenverCoder1/github-readme-streak-stats/issues/872">#872</a></li>
</ul>
<p><em>Last verified: Oct 14, 2026.</em></p>
]]></content:encoded></item><item><title><![CDATA[5 GitHub Profile README Templates You Can Copy (and How to Keep Them Short)]]></title><description><![CDATA[Most GitHub profile READMEs I see fall into two groups: an empty "Hi there 👋" left over from the default template, or a wall of badges, GIFs, and five…]]></description><link>https://githubcard.hashnode.dev/5-github-profile-readme-templates-you-can-copy-and-how-to-keep-them-short</link><guid isPermaLink="true">https://githubcard.hashnode.dev/5-github-profile-readme-templates-you-can-copy-and-how-to-keep-them-short</guid><category><![CDATA[GitHub]]></category><category><![CDATA[markdown]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[Beginner Developers]]></category><dc:creator><![CDATA[Colin]]></dc:creator><pubDate>Tue, 13 Oct 2026 13:46:28 GMT</pubDate><content:encoded><![CDATA[<p>Most GitHub profile READMEs I see fall into two groups: an empty "Hi there 👋" left over from the default template, or a wall of badges, GIFs, and five stats widgets stacked on top of each other. Neither tells a visitor much.</p>
<p>I've rewritten mine a few times. Below are five templates I'd actually use, depending on what kind of developer you are, plus a few rules that keep them from rotting.</p>
<h2>First: the 30-second setup</h2>
<p>If you haven't made one yet:</p>
<ol>
<li>Create a new <strong>public</strong> repository with exactly the same name as your GitHub username (e.g. <code>octocat/octocat</code>).</li>
<li>Add a <code>README.md</code> to it.</li>
<li>Whatever is in that file shows up at the top of your profile.</li>
</ol>
<p>That's it. Everything below is just Markdown (plus a bit of HTML that GitHub allows).</p>
<h2>Template 1: The minimal one</h2>
<p>Good if you don't want to maintain anything. Three lines of who you are, three links, done.</p>
<pre><code class="language-markdown"># Hi, I'm Sam

Backend developer. I mostly work on Go services and Postgres.
Currently: building internal tooling at a logistics startup.

- Blog: https://example.dev
- X: https://x.com/yourhandle
- Email: you@example.dev
</code></pre>
<p>Honestly, this beats most "fancy" profiles. A recruiter or another dev can read it in five seconds.</p>
<h2>Template 2: The open source maintainer</h2>
<p>If people land on your profile because of a project, send them back to it. Pin the repos too, but a short list with one-line descriptions does more than pins alone.</p>
<pre><code class="language-markdown"># Sam Doe

I maintain a few small libraries for working with CSV and time series data.

## Projects

| Project | What it does |
|---|---|
| [fastcsv](https://github.com/you/fastcsv) | Streaming CSV parser, zero deps |
| [tsbucket](https://github.com/you/tsbucket) | Downsample time series in the browser |

## Contributing

Issues and PRs welcome. Start with anything labelled `good first issue`.
</code></pre>
<p>Tables render fine on GitHub and stay readable on mobile as long as you keep them to two or three columns.</p>
<h2>Template 3: The job seeker</h2>
<p>Here the goal is to answer "what can this person do, and can I see proof?" quickly.</p>
<pre><code class="language-markdown"># Sam Doe — Full-stack developer

React, TypeScript, Node.js, PostgreSQL. 4 years shipping SaaS products.

**Open to:** remote full-stack roles

## Things I've built
- **Invoicer** — multi-tenant billing app (Next.js, Stripe). [Live](https://example.dev) · [Code](https://github.com/you/invoicer)
- **Queue-lite** — Postgres-backed job queue. [Code](https://github.com/you/queue-lite)

## Contact
you@example.dev · [LinkedIn](https://linkedin.com/in/you)
</code></pre>
<p>Put "open to" near the top. People skim.</p>
<h2>Template 4: The writer</h2>
<p>If you blog, your profile can act as an index. You can update the list by hand, or automate it with a GitHub Action that pulls your RSS feed (there are several on the Marketplace; search "blog post workflow").</p>
<pre><code class="language-markdown"># Sam Doe

Fullstack developer. Writing about system design.

## Recent posts
&lt;!-- BLOG-POST-LIST:START --&gt;
- [Designing idempotent webhooks](https://example.dev/idempotent-webhooks)
- [Why I stopped using ORMs for reporting queries](https://example.dev/orm-reporting)
&lt;!-- BLOG-POST-LIST:END --&gt;
</code></pre>
<p>The HTML comments are markers that RSS actions typically use to know where to write. They're invisible on the rendered page.</p>
<h2>Template 5: The stats-and-visuals one</h2>
<p>This is the template most people actually want: a short intro plus some visual summary of your GitHub activity: stats, top languages, streak, contribution graph.</p>
<p>The usual way to do this is to stack several embeds from different services:</p>
<pre><code class="language-markdown">![Stats](https://github-readme-stats.vercel.app/api?username=you&amp;show_icons=true)
![Top langs](https://github-readme-stats.vercel.app/api/top-langs/?username=you&amp;layout=compact)
![Streak](https://streak-stats.demolab.com?user=you)
![Activity](https://github-readme-activity-graph.vercel.app/graph?username=you)
</code></pre>
<p>It works, but each one has its own theme parameters, and they never quite line up visually. When one of the services is down or rate limited, you get a broken image in the middle of your profile.</p>
<p>The alternative I've been using is to put all of that into one image. Full disclosure: I work on <a href="https://githubcard.com">GitHubCard</a>, which does exactly this. You drag widgets (profile stats, streak, contribution heatmap, top languages, top repos, star history, and so on) onto a canvas, theme them once, and embed a single SVG:</p>
<pre><code class="language-markdown"># Hi, I'm Sam 👋

Full-stack developer building useful products.

![GitHubCard](https://githubcard.com/you.svg)

## Featured projects
- ...
</code></pre>
<p>Replace <code>you</code> with your username. With no custom design it renders a default card; if you design and save one in the editor (that part needs a GitHub sign-in), you copy the link it gives you instead. Data refreshes from GitHub but is cached, so changes can take up to an hour to show. For a repo, the same idea works with <code>githubcard.com/owner/repo</code>.</p>
<p>Whatever tool you use, the point is the same: one visual, not six.</p>
<h2>Rules I use to keep a profile README useful</h2>
<p><strong>1. Keep the top 10 lines for the important stuff.</strong> On a laptop screen, that's roughly what people see before scrolling. Name, what you do, what you're working on, how to reach you.</p>
<p><strong>2. Don't list every technology you've touched.</strong> A row of 30 logo badges says "I've opened a lot of tutorials". Five you'd be comfortable being interviewed on is more convincing.</p>
<p><strong>3. Avoid anything that goes stale.</strong> "Currently learning Rust" from 2022 is worse than nothing. If you include a "currently" line, either update it or automate it.</p>
<p><strong>4. Check it on mobile.</strong> Open your profile on your phone. Wide tables, side-by-side images with <code>align="left"</code>, and huge GIFs often fall apart there.</p>
<p><strong>5. Watch the number of external images.</strong> Every embed is another request to another service. Fewer embeds means a faster profile and fewer broken-image icons.</p>
<p><strong>6. Use alt text.</strong> <code>![GitHub stats for Sam](...)</code> instead of <code>![](...)</code>. It helps screen readers, and it's what shows when an image fails to load.</p>
<h2>A combined starter you can copy</h2>
<p>If you just want something to paste and edit:</p>
<pre><code class="language-markdown"># Hi, I'm &lt;Name&gt; 👋

&lt;One line: what you do.&gt; &lt;One line: what you're working on now.&gt;

![GitHub profile card for &lt;username&gt;](https://githubcard.com/&lt;username&gt;.svg)

## Featured projects
- **[project-one](https://github.com/&lt;username&gt;/project-one)** — what it does, in one line
- **[project-two](https://github.com/&lt;username&gt;/project-two)** — what it does, in one line

## Writing
- [Your best post](https://example.dev/post)

## Contact
&lt;email&gt; · [X](https://x.com/&lt;handle&gt;)
</code></pre>
<p>Swap the image line for whatever stats setup you prefer, or delete it. The rest is the part that actually tells people who you are.</p>
<p>If you have a profile README you're proud of, drop the link in the comments. I'm always looking for layouts to steal.</p>
]]></content:encoded></item><item><title><![CDATA[How to Add a GitHub Streak Stats Card to Your Profile README (Without Another Service)]]></title><description><![CDATA[A commit streak is one of the most popular things people put on their GitHub profile. It's a quick signal that you ship regularly. This guide covers how to…]]></description><link>https://githubcard.hashnode.dev/how-to-add-a-github-streak-stats-card-to-your-profile-readme-without-another-service</link><guid isPermaLink="true">https://githubcard.hashnode.dev/how-to-add-a-github-streak-stats-card-to-your-profile-readme-without-another-service</guid><category><![CDATA[GitHub]]></category><category><![CDATA[Open Source]]></category><category><![CDATA[webdev]]></category><dc:creator><![CDATA[Colin]]></dc:creator><pubDate>Mon, 12 Oct 2026 10:01:53 GMT</pubDate><content:encoded><![CDATA[<p>A commit streak is one of the most popular things people put on their GitHub profile. It's a quick signal that you ship regularly. This guide covers how to add one, and how to keep it from becoming yet another image embed you have to babysit.</p>
<h2>Step 1: Set up your profile README</h2>
<p>If you don't have one yet:</p>
<ol>
<li>Create a <strong>public</strong> repository with the exact same name as your username (e.g. <code>alex/alex</code>).</li>
<li>Add a <code>README.md</code>.</li>
</ol>
<p>GitHub renders that file at the top of your profile.</p>
<h2>Step 2: Add a card with streak stats</h2>
<p>The usual approach is a dedicated streak service with its own URL and theme parameters. If you already use separate cards for stats and languages, that's another host and another set of colors to match.</p>
<p>An alternative is to put the streak on the same card as everything else. With <a href="https://githubcard.com/">GitHubCard</a>, a default card is a single URL, no sign-in needed:</p>
<pre><code class="language-md">[![GitHub card](https://githubcard.com/YOUR_USERNAME.svg)](https://github.com/YOUR_USERNAME)
</code></pre>
<h2>Step 3: Make the streak the focus (optional)</h2>
<p>If you want the streak front and center:</p>
<ol>
<li>Open the canvas editor at <a href="https://githubcard.com/">https://githubcard.com/</a> and pick a profile card.</li>
<li>Enter your username.</li>
<li>Drag in the <strong>Streak Stats</strong> widget and resize it as the main element.</li>
<li>Add supporting widgets if you like: <strong>Contributions Heatmap</strong>, <strong>Profile Stats</strong>, <strong>Language Donut</strong>.</li>
<li>Set one theme for the whole card, then export as SVG (or PNG for social posts and slides).</li>
</ol>
<p>Saving and updating a custom design requires signing in with GitHub.</p>
<h2>Things to know</h2>
<ul>
<li><strong>Freshness:</strong> cards use live GitHub data with caching, so changes can take up to about an hour to appear. Don't panic if today's commit doesn't show immediately.</li>
<li><strong>Cost:</strong> core features are free, per the site's FAQ.</li>
<li><strong>Repos too:</strong> the same pattern works for repositories: <code>https://githubcard.com/OWNER/REPO.svg</code>.</li>
</ul>
<h2>A note on streaks</h2>
<p>Streaks are motivating, but they're not a measure of quality. Many solid engineers have gaps because they work in private repos or take weekends off. Treat a streak card as a small signal on your profile, not the headline. Pair it with pinned projects and a short line about what you build.</p>
<hr />
<p><em>I build GitHubCard. If you try it, I'd genuinely like to hear what's missing.</em></p>
]]></content:encoded></item></channel></rss>