DEV Community

Cover image for Python 3.10 end of life is Oct 31: find every pinned Python and Node version
Versyka
Versyka

Posted on AI-assisted

Python 3.10 end of life is Oct 31: find every pinned Python and Node version

Python 3.10 reaches end of life on October 31, 2026. Node 20 already did, on April 30, 2026.

End of life doesn't break anything. The interpreter keeps running. What stops is security releases: the next CVE in that version never gets a patch, and nothing in your build turns red to tell you.

The hard part isn't upgrading. It's knowing where the version is pinned, because it's rarely in one place.

Where runtime versions hide

File What it looks like
Dockerfile FROM python:3.10-slim, FROM node:20-alpine
.python-version 3.10 or 3.10.14
runtime.txt python-3.10.14 (Heroku-style platforms)
.nvmrc / .node-version 20
serverless.yml runtime: python3.10, runtime: nodejs20.x
pyproject.toml requires-python = ">=3.10,<3.11"
package.json "engines": { "node": "20.x" }
CI config python-version: "3.10", node-version: 20

A quick audit script

Run this from the root of a repository:

#!/usr/bin/env bash
# Find pinned Python 3.10 and Node 20 runtimes
grep -RInE \
  --include=Dockerfile* --include=.python-version --include=runtime.txt \
  --include=.nvmrc --include=.node-version --include=serverless.y*ml \
  --include=pyproject.toml --include=package.json --include=*.yml --include=*.yaml \
  -e 'python:?3\.10' -e 'python-?3\.10' -e 'python3\.10' -e '"3\.10' \
  -e 'node:20' -e 'nodejs20' -e '^20(\.|$)' -e 'node-version: *"?20' \
  . 2>/dev/null | grep -v node_modules
Enter fullscreen mode Exit fullscreen mode

It's noisy on purpose. A false positive costs you two seconds. A missed FROM python:3.10 costs you a year of unpatched base images.

What to move to

Check endoflife.date before you pick. As of today:

  • Python: 3.10 ends Oct 31, 2026. Move to a version with years of support left, not the next one up.
  • Node: 20 ended Apr 30, 2026. Node 22 is supported until Apr 30, 2027, so a move to 22 buys you six months. Plan for the one after it at the same time.

Make it someone's job (or something's)

The audit above works once. The dates keep coming, though: there's a runtime end of life every few months across Python, Node, Ruby, Go and Java.

That's why we made it a daily check in Versyka, for Python and Node.js. It reads .python-version, .nvmrc and .node-version, runtime.txt, your Dockerfiles, and the runtime in serverless.yml or a SAM template.yaml. Then it checks each pinned version against endoflife.date and warns you 180 days before the date, by email, Slack and on the dashboard. It alerts only: changing a base image is a decision you should make, not a bot. (A minimum like requires-python = ">=3.8" isn't a pin, so it doesn't count.)

Whatever you use, get the dates on a calendar before they pass.

Top comments (0)