A libyear is the time gap between the version of a dependency you use and the newest release, summed across your dependencies. One year behind equals one libyear. It is a simple freshness signal. It is useful as a trend line for a quarter, but a poor target on its own.
How the number is calculated
The libyear project gives a plain example: Rails 5.0.0, released in June 2016, is one libyear behind 5.1.2, released in June 2017. If a system has a one-year-old dependency and a three-year-old one, the whole system is four libyears behind. You add the gaps together.
The appeal is that you can explain it in thirty seconds. The project publishes tools for several ecosystems, including npm, PyPI, Bundler, Cargo, Go modules, Maven, Gradle, NuGet and Composer, so most teams can produce a number without writing code.
The same page mentions two related measures from academic work on dependency freshness: how many major, minor or patch versions behind a dependency is, and how many releases sit between your version and the latest.
What the number tells you
- Direction. If the figure rose from last quarter, drift is growing faster than you pay it down.
- Concentration. Sorting by libyears per dependency shows where the gap lives. One neglected package can be most of the total.
- Effort proxy. A larger gap tends to mean a larger, riskier jump later, although that is a tendency, not a law.
What it misses
Be clear about the limits before you put it on a slide.
| Blind spot | Why it matters |
|---|---|
| No severity | A year-old package with no advisories counts the same as one with an exploited flaw |
| No reachability | It does not know whether you call the vulnerable code |
| Release cadence differs | A slow-moving library can be old and still correct |
| Rewards chasing the newest | Latest is not always safest, see our note on release cooldown policies |
For these reasons, libyears describe maintenance burden, not security risk. Pair the number with advisory and reachability data.
Should you set a quarterly target?
Targets change behaviour. A target on a raw libyear total invites two bad moves: upgrading easy, harmless packages to move the number, and avoiding new dependencies that would raise it, even when they are the right choice.
A safer pattern:
- Record the baseline this quarter and publish it to the team.
- Set a direction goal, such as "do not let it grow", instead of an absolute number.
- Add a separate, hard rule for anything with a reachable advisory or an end-of-support date inside the quarter.
- Review the top five contributors each quarter and decide, one by one, whether to upgrade or consciously defer.
Our guide to measuring dependency freshness in CI covers the mechanics of collecting the number on every build.
Reading it with context
Report the total, the top contributors, and how many of those carry a known advisory. Three figures tell the story better than one. If a single abandoned package makes up most of the gap, the decision is replace or remove, not upgrade.
Where Safeguard fits
Safeguard's dependency scanning lists versions across your repositories and ties them to advisories, so a freshness number can sit next to exposure data. A free scan is at gold.safeguard.sh/scan.
Quick check
Is a lower libyear always better?
Not automatically. It signals less drift, but it says nothing about severity, and chasing it can push you onto very new releases.
Who coined libyear?
The libyear site credits its definition to the project's maintainers and cites a 2015 ICSE paper on measuring dependency freshness for related metrics.
Sources
Last reviewed: 19 October 2026.