End-of-Life Checker
Drop in a project folder, a Dockerfile or a package.json to see which runtimes, base images and frameworks are past or near their end of life, and what to move to.
How the check works
- Find what the project runs on. Each file is read for the versions it names: the image and OS release in every Dockerfile FROM line (multi-stage builds included, with the final image marked), runtime versions in version files and project files, and framework versions in package.json, package-lock.json, pyproject.toml and requirements files.
- Match each version to its release line. 20.11.0 belongs to Node.js 20,
net8.0 to .NET 8, bookworm to Debian 12. A range counts as the oldest version it allows, and
a floating tag like
latestorltsas the release it points to today. - Place it on its timeline. Using the release’s published dates, we work out where it is today and when that changes, and show the newest release still getting fixes.
Anything we can’t match, such as a private image or a version with no published dates, is listed under “not checked” rather than guessed.
Supported, security only, extended, end of life
- Supported: bug fixes and security fixes are still released.
- Security fixes only: the release is in maintenance; only security problems are fixed. A good time to plan the upgrade.
- Extended support only: the regular support has ended, but extended support is still offered, usually paid or through a separate programme (for example Ubuntu Pro’s Expanded Security Maintenance or Debian LTS). Without it, treat the release as end of life.
- End of life: no more fixes, including for security problems found from now on.
On each timeline the bar shows those phases, the vertical line is today, and a bar that fades out means no end date has been published yet.
Frequently asked questions
Which files does it read?
Dockerfiles (every FROM line, and the OS release a tag names, like -bookworm or -alpine3.20), package.json and package-lock.json (the Node.js version in engines, and React, Angular, Vue, Next.js, Nuxt, Electron and Express), .nvmrc and .node-version, .python-version, runtime.txt, pyproject.toml and requirements files (Python and Django), .csproj, .fsproj and .vbproj target frameworks, global.json, go.mod, .ruby-version and .tool-versions.
Are my files uploaded?
No. The folder is read in your browser, and only the files above are opened; node_modules, .git and build folders are skipped without being looked at. The one thing sent to our server is the name of an image whose tag doesn’t say which OS release it is built on (like node:22-alpine), so we can read that from Docker Hub.
What do the four statuses mean?
Supported: the release still gets bug and security fixes. Security fixes only: only security problems are still fixed. Extended support only: the free support has ended, but paid or long-term support is still sold (Ubuntu Pro, Debian LTS, commercial Node.js support and similar). End of life: no fixes of any kind. Each product names its own phases slightly differently; the row links its release policy.
Why does a range like ">=18" count as Node.js 18?
A range lets a project run on any version it allows, including the oldest. We show the oldest one, because that is the one that reaches end of life first. If you always run something newer, raise the range so it says so.
Why is node:22-alpine checked against a specific Alpine release?
A tag like -alpine or no OS suffix at all doesn’t say which release the image is built on. That’s whatever the image’s maintainers built it on, which isn’t always the newest one, so we read it from the image’s build steps on Docker Hub. Images on other registries don’t publish those steps, so their base OS is listed as not checked.
Where do the dates come from?
From endoflife.date, a community-maintained, MIT-licensed collection of release and support dates for hundreds of products, each linked to its vendor’s own release policy. We download it every day and refuse a download that looks broken or much smaller than the last one, so stale dates are kept rather than lost. For Node.js, Python, .NET, Go, PHP, Debian, Ubuntu and Alpine Linux we also compare the dates with the vendor’s own schedule every day, and show both when an upcoming one differs.
Which version should I move to?
The row shows the newest release that still gets fixes, and for products with long-term support releases (Node.js, Ubuntu, .NET, Django) the newest LTS one. Whether that move is easy depends on your code; read the product’s release notes before upgrading.
Where the dates come from
Release and support dates for 484 products come from endoflife.date, maintained by its contributors on GitHub and published under the MIT License. Every row links the product’s endoflife.date page and, where it lists one, the vendor’s own release policy, which is the final word on its dates.
We download the full list every day. A download that’s broken, or much smaller than the last one, is refused and the previous dates are kept. Base OS releases of images whose tag doesn’t name one are read from the image’s build steps on Docker Hub when you run a check.
For Node.js, Python, .NET, Go, PHP, Debian, Ubuntu and Alpine Linux, the dates are also compared every day with the vendor’s own published schedule. If an upcoming date differs, the result shows both dates and links the vendor’s page, so you can go by the vendor.
See Methodology & sources for how our checks work.