Node 20 Will Be Deprecated on Github Actions Runners
Posted4 months agoActive3 months ago
github.blogTechstoryHigh profile
calmmixed
Debate
60/100
Node.jsGithub ActionsDevops
Key topics
Node.js
Github Actions
Devops
GitHub is deprecating Node 20 on its Actions runners, prompting discussions about the implications for developers, particularly those using self-hosted runners or maintaining older projects.
Snapshot generated from the HN discussion
Discussion Activity
Very active discussionFirst comment
2h
Peak period
40
36-48h
Avg / period
7.9
Comment distribution63 data points
Loading chart...
Based on 63 loaded comments
Key moments
- 01Story posted
Sep 20, 2025 at 7:19 AM EDT
4 months ago
Step 01 - 02First comment
Sep 20, 2025 at 9:36 AM EDT
2h after posting
Step 02 - 03Peak activity
40 comments in 36-48h
Hottest window of the conversation
Step 03 - 04Latest activity
Sep 26, 2025 at 11:53 PM EDT
3 months ago
Step 04
Generating AI Summary...
Analyzing up to 500 comments to identify key contributors and discussion patterns
ID: 45312323Type: storyLast synced: 11/20/2025, 2:35:11 PM
Want the full context?
Jump to the original sources
Read the primary article or dive into the live Hacker News thread when you're ready.
OTOH I've been moving from native NodeJS actions to packing them in a Docker container to separate code from compiled code.
If you wanted to use Typescript for your action you always had a 2 step process because GitHub Actions required you to pack dependencies with ncc or vite or webpack.
This packaged version was subsequently committed to the main branch.
Technically I could do a composite action where I compile the typescript on the fly, but that was fragile last time I tried it.
https://bsky.app/profile/danielroe.dev/post/3lxczp5apec2x
https://nodejs.org/api/cli.html#--experimental-transform-typ...
https://vercel.com/docs/functions/runtimes/node-js/node-js-v...
Yet with GHA I need to update actions/checkout@v2 to actions/checkout@vwhatever (or, what I'm doing now, actions/checkout@main because the actual API haven't actually changed) because... some Node version is "out of maintenance"?!
GHA is literally code execution as a service. Why would I care whether the Node runner has a security vulnerability?
I’m guessing they know you don’t care, but the big company customers cant have a CVE anywhere and won’t accept a EOL node version so they can check a box on something.
(I guess there’s also people with self hosted runners, who might be running them inside networks that aren’t segmented.)
"Why do I care if there is a potentially insecure code interpreter in my arbitrary code execution service?"
As someone where appsec is a component of my work in financial services, please believe you should care.
Perhaps having had to run down potential exposure across a large enterprise from the recent npm supply chain attack has made me a bit more paranoid lately around supply chain and cicd security. But, I get paid to be paranoid, so it is what it is. Run your own runners I suppose? Hard to complain when someone else is running the infrastructure for you (and you’re not paying enterprise prices). Supply chain and hosted/multi tenant execution code security is just fundamentally hard and fraught with peril. Ongoing deprecations to keep up with current state are therefore unavoidable.
If you want to run builds with old containers running old code on your personal equipment, sure, that’s fine, the impact is likely limited to you. A person has little financial, liability, or reputational risk.
The article shows that such an option does exist. But it will be phased out in 3 stages, making it impossible to run node 20 eventually. This really does disrupt the standard software development practice of reproducible builds. Safety determinations must be implemented orthogonally to reproducible builds.
Ultimately, this is the next stage in the war on computing freedom and general purpose computing. They're moving from "We decide what you're allowed to run." to "We decide what you're allowed to develop." I know that many will object to this calling it an overreaction and claim that nobody is forced to use their CI/CD system. But as history has shown time and again, lock-in and restrictions come in numerous small doses that are individually too small to trigger the alarm bells among the general population.
Because at the end of the day, Github is responsible for _their_ runners.
If you want full control, install and use your own runners, which flips the responsibility to you.
It's a bit tedious to have to explain that service providers have certain responsibilities and obligations too. Corporate culture has given bigtech a blank cheque to behave the way they want. That aside, based on the way you framed your reply, let me assure you that I don't trust them with even my projects, much less the CI system or their runner. And time and again, they vindicate that decision. I have posted the full argument as a reply to your sibling comment.
go buy some servers, put any github lookalike service in there and you are completely free to run with Node v1 if you really want.
By ruining build reproducibility through such short sighted decisions, you are actually compromising a security measure. And I already proposed a way to overcome this problem if you insist on disabling node 20 by default - provide a way to explicitly override it when needed.
Besides, the security model you suggest isn't even the correct way to deal with supply chain vulnerabilities. They have to be version-flagged at the artifact distribution point, not at the CI stage by unilaterally imposing backwards-incompatible restrictions.
> Computing freedom applies only on machines YOU control. you can't expect to be able to do everything you want on hardware others control.
There are two fundamental issues with that argument here. Any user depends on services like these after entering an agreement with a service provider (Github). Even free tier users agree to the ToS. This is significant because the developer(s) are making an investment on the provider's service. GAs are not seamlessly transferrable to any competing service, even ones that try to replicate GA. The users are basically soft locking themselves in to the platform. It takes nontrivial effort from the user if they want to migrate away. In such situations, it's only ethically and morally correct for the service provider to never blindly pull the rug from under the users like this. This is especially true with paying customers.
The second problem with that argument is that it's not fair for the service provider to keep shifting the goal post once the restrictions have been agreed upon by both parties. In case of GA, the developers are not doing whatever they please on Github's servers. Their actions are executed within a restricted context with predefined restrictions. Any damage is restricted to that context and is ephemeral. Arbitrary modification of those restrictions later on only creates headache for the developers without any meaningful benefits.
> go buy some servers, put any github lookalike service in there and you are completely free to run with Node v1 if you really want.
I stay away from GH as much as possible precisely because this uncaring attitude of theirs. As I explained earlier, it's not trivial to migrate even to GA lookalikes. I would rather target a different platform that wouldn't randomly rugpull from under me like this.
My day job org is a Github customer with a few hundred thousand dollars of annual spend with them, so while we get their ear, we don't move the needle with regards to product changes (their customer success team is very helpful when they can be though). I imagine the situation is not as great if you are a free user, or someone with immaterial spend with them; you're simply along for the ride.
As always, do what is best for your risk and threat model.
That's what I do and it's pretty stable: https://github.com/alshdavid-templates/siteforge/blob/main/....
Couple more thoughts and unsolicited feedback from a quick eyeball:
- Use https://
- Wrap everything in a shell function to ensure that partial content is not executed.
- Wrap variable substitutions with "${OUTPUT_DIR}" to prevent arg splitting if they contain whitespace. Line 124, `rm -rf $OUT_DIR_INSTALL` is pretty scary if invoked with whitespace in OUT_DIR.
- Download nodejs tarball to temp directory and then extract them to prevent partial extraction
When I build my software I care less about eliminating security vulnerabilities (after all, I need to build while updating to fix security issues), but also don't need, or ideally don't want any external access. A vulnerability in the build toolchain should be encoded into the artifacts but shouldn't necessarily prevent artifacts being generated.
However when I automate processes, like categorising bugs etc, I care a lot about eliminating security vulnerabilities because there is necessary external access, often write access, to my sensitive data.
GitHub considers these two things the same, but they're distinct use-cases with distinct approaches to maintenance, updating, and security.
As in, kills your old build code dead?
Because that "build" process has free access to your repo and potentially your organization. If your repo is also where you deploy from, then potentially deploying a vulnerable version of your software, live to your users.
Then don't use Docker. You never know the image you are using will be outdated.
Just update your dependencies, it's not that hard. And it's even easier when you do it routinely as part of a deprecation planning.
...wait, really?
I have NodeJS 24 working all the way back on macOS 10.9 [1]. I realize official support is a very different thing, but I'm still surprised they can't do better than Ventura.
1: https://github.com/Wowfunhappy/Node-24-Mavericks/blob/master...
It's re-implementation of the GHA self-hosted runner in Go for self-hosted runners, based on the popular https://github.com/nektos/act for running GHA locally. Been using this for over a year now and it's been infinitely useful for CI on otherwise unsupported systems (e.g. freeBSD, openBSD in my case).
> Local Task Runner - I love make. However, I also hate repeating myself. With act, you can use the GitHub Actions defined in your .github/workflows/ to replace your Makefile!
This is ass backwards. Throwing out a tried and true build system in favor of a vendor-specific yaml format? Wtf? Just invoke make from your actions ffs.
The tool is here to run GHA tasks locally, period. It's not a replacement for a Makefile.
And I agree with you: use `make` in your actions!
If I want to make sense of the sentence, the only thing I can think of is that, before making this tool, they were using a Makefile locally to replicate the content of their GHA tasks.
Instead use mise tasks.
There's many projects in the real world where they're not touched by a developer in a given year. That doesn't mean they're broken or stale, the opposite, it means they're such great tools that they don't need changing.
It's a bit of an annoying hassle that frankly is not an issue in many other languages.