feat: default (runtime) Node.js version
๐ Linked issue
Closes #2716
โ Type of change
- [ ] ๐ Documentation (updates to the documentation, readme, or JSdoc annotations)
- [ ] ๐ Bug fix (a non-breaking change that fixes an issue)
- [x] ๐ Enhancement (improving an existing functionality like performance)
- [ ] โจ New feature (a non-breaking change that adds functionality)
- [ ] ๐งน Chore (updates to the build process or auxiliary tools and libraries)
- [ ] โ ๏ธ Breaking change (fix or feature that would cause existing functionality to change)
๐ Description
A preset should accept the user's choice of Node.js runtime, as long as it is supported by the platform. In cases where the user's choice is not supported, or the user does not specify a runtime, a sensible default/fallback should be used.
Currently, the fallback is defined per preset. However, to ensure all deploy providers behave uniformly, we should define this globally at the Nitro level.
See https://github.com/unjs/nitro/pull/2654#discussion_r1746677267 for reference.
Methodology
To decide an appropriate fallback, we need to know two pieces of information:
- Node versions supported by the platform
- How to define a runtime from a node version
To do this, we can export a getDefaultNodeVersion utility which takes the supported Node versions as a set of numbers, and a function to convert the number to a runtime defintion. It then compared this to a globally set default. As Nitro is updated and newer Node features are used, this global can be increased to bump all presets.
Examples
const supportedNodeVersions = new Set([18, 20]);
const defineRuntime = (version) => `nodejs-${version}`;
const default = getDefaultNodeVersion(supportedNodeVersions, defineRuntime);
const supportedNodeVersions = new Set([16, 18, 20]);
const default = getDefaultNodeVersion(supportedNodeVersions, String);
Considerations
This utility should consider the case where the Nitro default is not supported by the platform yet.
The documentation for preset authors should be updated to only list GA node versions in supportedNodeVersions.
๐ Checklist
- [x] I have linked an issue or discussion.
- [ ] I have updated the documentation accordingly.
Hi @pi0 I have written up my idea and implemented it into a couple of presets. Before I continue and implement it into others, I thought it would be wise to seek some feedbadk.
What do you think of the idea? Do you think the utilities and constants are located in the right places? Is there anything else you would like me to consider?
@luc122c is attempting to deploy a commit to the Nitro Team on Vercel.
A member of the Team first needs to authorize it.
The latest updates on your projects. Learn more about Vercel for Git โ๏ธ
| Name | Status | Preview | Comments | Updated (UTC) |
|---|---|---|---|---|
| nitro.build | โ Ready (Inspect) | Visit Preview | ๐ฌ Add feedback | Jul 15, 2025 4:09pm |
Hi dear @luc122c i love this idea sorry i couldn't check earlier. Please let me back on this, perhaps we can introduce in v3 branch first (also we should drop 16, 18 :D)
@pi0 no problem at all! I forgot about it too ๐
Yes, I will target the v3 branch, make 20 the minimum and try to finish it off. Thanks for your support :)
Well, this rebase has turned into a great big mess ๐ I might close this and start a new branch and cherry-pick the relevant commits.
It looks like Nitro no longer needs to specify the node version in the preset for Firebase App Hosting. The buildpack picks it up from package.json.
@pi0 I have refactored the function to take the node version in package.json into consideration. I have also applied it to all applicable presets.
I've tried to make it as simple as possible to apply this to other presets. Is there anywhere you'd like me to write any documentation for this?
This has become much more relevant since Sept 23 when AWS Amplify dropped support for Node 18. The temporary work around I have found is this: https://repost.aws/questions/QUlWLs6Z1lSTG791VP-Hf3XA/nuxt-vue-app-stopped-deploying-sep-23-2025-with-error-message-customererror-we-failed-to-validate-the-deploy-manifest-json-file-found-in-your-build-output-directory
It would be great if we could have a way to change the automatically generated deploy-manifest that is currently defaulting to node 18 with Nuxt 3. (Hopefully this is the correct place to make this request)
This PR is targetting nitro v3 (upcoming nuxt) i will review ASAP.
@Rothalack If AWS needs a hotfix please feel free to make a PR against v2 branch for it specifically we can land it sooner.
Thanks for the quick reply @pi0
I did a deeper dive through things before I went making a PR, making sure I really understood everything.
I was on Nuxt 3.17.2, which uses Nitro 2.11.11, which defaults to Node 18. I found that Nuxt 3.2, uses Nitro 2.12.9, which defaults to Node 20. Effectively doing exactly what I was hoping to find. So I think what I was asking for has already been solved.
Thanks!