For a while, typing claude --version over my morning coffee was a reflex. Some days the number matched yesterday's, some days it had jumped by two, and each time I stalled on the same question: should I read the changes today?
I wanted to stop answering that by feel, so I counted the publish history itself. What follows are the numbers I pulled from the npm registry on the morning of November 6, 2026, and the line I drew from them.
The point I most want to share first: decide how often to follow updates from measured publish gaps, not from mood.
The result, up front
The package is @anthropic-ai/claude-code on npm. For the last 28 days (October 9 to November 6):
| Item | Value |
|---|---|
| Releases published | 21 (about 5.2 per week) |
| Median gap between releases | about 23 hours |
| Shortest gap | about 3.6 hours |
| Longest gap | about 103 hours (a little over 4 days) |
Releases newer than dist-tag latest | 1 |
Releases newer than dist-tag stable | 7 |
"Something ships almost every day" matched my impression. But there are also valleys of four days or more, and on nearly half of my mornings the check showed nothing new or one small fix.
One more detail: 2.1.0 through 2.1.319 spans 320 numbers, yet only 275 releases exist. Version numbers skip, so I avoid subtracting them to find "how far behind" I am and count published releases instead. I covered that in Two Default-Model Changes Haven't Reached Claude Code's Stable Channel Yet.
The counting script
It runs on the standard library alone. Sorting by publish time is the part that matters.
import json
import urllib.request
import datetime as dt
from statistics import median
URL = "https://registry.npmjs.org/@anthropic-ai/claude-code"
DAYS = 28
with urllib.request.urlopen(URL, timeout=30) as r:
meta = json.load(r)
times = meta["time"]
since = dt.datetime.now(dt.timezone.utc) - dt.timedelta(days=DAYS)
# Sort by publish time, not by version number
releases = sorted(
(dt.datetime.fromisoformat(times[v].replace("Z", "+00:00")), v)
for v in meta["versions"]
if v in times and "-" not in v # skip pre-release tags
)
recent = [(t, v) for t, v in releases if t >= since]
gaps_h = [
(b[0] - a[0]).total_seconds() / 3600
for a, b in zip(recent, recent[1:])
]
print(f"Published in the last {DAYS} days: {len(recent)} ({len(recent) / DAYS * 7:.1f} per week)")
print(f"Median gap: {median(gaps_h):.1f} h / min {min(gaps_h):.1f} / max {max(gaps_h):.1f}")
for tag, ver in meta["dist-tags"].items():
ts = dt.datetime.fromisoformat(times[ver].replace("Z", "+00:00"))
behind = sum(1 for t, v in releases if t > ts)
print(f"{tag:7s} {ver:9s} {behind} newer releases published")Releases without an entry in time are skipped so a missing timestamp can't crash the run. The output has the same three-part shape as the table above.
Three things I noticed
First, the median is under a day but the longest gap is over four. If you assume "it updates daily" and check every morning, the valley days are wasted checks.
Second, latest was one release behind while stable was seven behind. Both are "published," yet the distance differs a lot, so which channel you follow changes what reaches your machine on the same day.
Third, before counting I had felt there were too many updates to follow. The real volume was about five per week, an amount a single weekly read can cover. It was nothing to lose sleep over.
The line I drew
- Leave auto-update on, and read the changes once a week, on Monday morning
- Before a deadline-heavy stretch, consider pinning a version
- If behavior seems to change mid-work, read the diff against the previous release that same day
If auto-update stalls in unexpected ways, Claude Code Auto-Update Not Working? A Practical Diagnosis Flow When claude --version Won't Move walks through the checks, and When Claude Code dies with a Bus error on a shared home directory, check this before you turn off auto-update covers a case where a running binary disappears.
Where the line helped in my own app work
Around an app-store submission I often use Claude Code to fix build settings and localized strings in one sweep. In the days before submitting, if my tools change a little every day, I can't tell whether a failure is my change or the tool's, and my hands stop.
So in submission weeks I check the version on Monday and then skip new releases for the rest of that week. Knowing the longest gap was a little over four days gave me a reason to believe that waiting wouldn't cost much. Without the number, I might have felt uneasy about pinning at all.
The window changes what you see
The 28 days is just the window I picked. At 14 days, the weeks where releases bunched up after a bigger feature stand out; at 90 days, things settle toward the average of about five a week.
No length is correct. A window of two to three times the cycle on which you read updates has worked well for me: if you read weekly, two to three weeks is a sensible range.
One next step
Run the script once on your own machine and look at your own window. Changing 28 days to 14 is enough to see how much the rhythm swings.
Following updates gets much quieter once you hold a single number. I intend to keep that habit as an indie developer who relies on these tools daily.