You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Node 24.x not yet marked as LTS ("Krypton") in index.json (website lists v24.10.0 as Latest LTS) #8277
Tools that rely on index.json (Volta, nvm, fnm, etc.) still treat Node 22 ("Jod") as the current LTS.
How often does it reproduce? Is there a required condition?
Always, until the index.json is updated to include "lts": "Krypton" for Node 24 entries.
What is the expected behavior? Why is that the expected behavior?
When Node 24 is promoted to LTS (codename "Krypton"), each v24.x entry in index.json
should have an "lts" field set to "Krypton" rather than false.
Tools and automation use this field to determine the latest LTS line,
so keeping it accurate ensures consistency between nodejs.org and the dist metadata.
What do you see instead?
All v24.x entries in index.json currently show "lts": false,
while the homepage lists v24.10.0 as “Latest LTS”.
The most recent version marked as LTS in index.json is still 22.21.0 ("Jod").
This discrepancy causes tools such as Volta, nvm, and fnm — which rely on index.json
to determine the current LTS — to continue installing Node 22 instead of 24.
This seems like a metadata lag during the LTS promotion.
Just filing it here in case the release metadata hasn’t yet been updated.
Thanks for maintaining Node.js and for your work on the release process 🙏
As of right now, the website is extremely data-driven, and we have found a number of places where missing data (ie: missing release overlaps, postponed or faulty releases, etc.) cause outages, only for it to correct once backing data is available.
I've said this several times but it seems my comment is always ignored: the source of truth is https://nodejs.org/download/release/index.json. You can stay data-driven if you use that.
Reacted by Antoine du Hamel, Nikita Skovoroda, Aviv Keller, Richard Lau, Jordan Harband and Claudio Wunder
In particular, curl https://nodejs.org/download/release/index.json | jq first always returns the latest Current, and curl https://nodejs.org/download/release/index.json | jq 'map(select(.lts)) | first' always returns the latest LTS.
It's one of those unfortunate types of issues that is wrong for a very short amount of time, but when naturally lots of eyeballs are drawn to the site.
I started looking into this. There are some reasons to use the nodevu logic. I think one solve would be to cross-reference it with the index.json to never OVERPROMISE release information that should be present based on a simple date comparison
I didn't look too close at the downstream usages, but it has a lot of date logic:
constsupport={currentStart: major.support.phases.dates.start,ltsStart: major.support.phases.dates.lts,maintenanceStart: major.support.phases.dates.maintenance,endOfLife: major.support.phases.dates.end,};// Get the major release status based on our Release Scheduleconststatus=getNodeReleaseStatus(newDate(),support);constminorVersions=Object.entries(major.releases).map(([,release])=>({modules: release.modules.version||'',npm: release.dependencies.npm||'',releaseDate: release.releaseDate,v8: release.dependencies.v8,version: release.semver.raw,versionWithPrefix: `v${release.semver.raw}`,}));
Here a small script that I had used to know what happened so not the website code
import{major}from'@vltpkg/semver';constINDEX_LINK="https://nodejs.org/download/release/index.json";constSCHEDULE_LINK="https://raw.githubusercontent.com/nodejs/Release/main/schedule.json";constreleasesData=awaitfetch(INDEX_LINK).then(res=>res.json());constscheduleData=awaitfetch(SCHEDULE_LINK).then(res=>res.json());constgetLatestLTS=(releases)=>releases.find(release=>release.lts!==false);constgetLatestCurrent=(releases,schedule)=>{consttoday=newDate();letcurrentMajor=null;letlatestStartTime=-Infinity;for(const[key,info]ofObject.entries(schedule)){if(!info||!info.start)continue;conststart=newDate(info.start);constend=info.end ? newDate(info.end) : null;if(isNaN(start))continue;// Consider schedule entries that have started and not yet endedif(start<=today&&(!end||today<end)){conststartTime=start.getTime();if(startTime>latestStartTime){latestStartTime=startTime;currentMajor=parseInt(key.replace(/^v/,''),10);}}}// fallback: if we couldn't find a matching schedule entry, pick the most// recently published non-LTS releaseif(!currentMajor){constnonLTS=releases.filter(r=>r.lts===false);if(!nonLTS.length)returnnull;returnnonLTS.sort((a,b)=>newDate(b.date)-newDate(a.date))[0];}// find releases matching the major and return the most recently published oneconstcandidates=releases.filter(r=>major(r.version)===currentMajor);if(!candidates.length)returnnull;returncandidates.sort((a,b)=>newDate(b.date)-newDate(a.date))[0];}constgetLTS=(releases)=>releases.filter(item=>item.lts!==false).reduce((acc,release)=>{constmajorVersion=major(release.version);if(!acc.find(item=>major(item.version)===majorVersion)){acc.push(release);}returnacc;},[]);constgetCurrent=(releases,schedule)=>{consttoday=newDate();constcurrentMajors=Object.entries(schedule).filter(([key,info])=>info&&info.start&&!isNaN(newDate(info.start))).filter(([key,info])=>{conststart=newDate(info.start);constend=info.end ? newDate(info.end) : null;returnstart<=today&&(!end||today<end);}).map(([key])=>parseInt(String(key).replace(/^v/,''),10)).filter(n=>!isNaN(n));if(!currentMajors.length)return[];constmajorsSet=newSet(currentMajors);returnreleases.filter(r=>majorsSet.has(major(r.version))).sort((a,b)=>{constma=major(a.version);constmb=major(b.version);if(ma!==mb)returnmb-ma;// higher major firstreturnnewDate(b.date)-newDate(a.date);// newer first within same major}).reduce((acc,release)=>{constmajorVersion=major(release.version);if(!acc.find(item=>major(item.version)===majorVersion)){acc.push(release);}returnacc;},[]).filter(r=>r.lts===false);};
Totally makes sense that there’s some drift here with these two sources and index.json should be prioritized. Probably worth looking at automating updating Scheudle.json since I know I’m not the only one relying on it :)
That said, totally agree about index.json being prioritized. In theory, should be pretty easy to check the data and see if index.json is more up to date and use that instead once we have that data - this is the exact kind of API smoothness I built nodevu to provide.
I’m about to get on a ~9 hour flight home from SFO, should be able to get a PR up in that time. Will reference this issue from it, should be a seamless fix for the website once published.
Reacted by Matt Cowley, Jordan Harband and Claudio Wunder
FYI, we hit this again in #8766. I've got a fix on our end up in #8787 to manually check the LTS status of the most recent release for each major. I do still agree with what has been said here before that this should really be something that nodevu does, where it doesn't report an LTS support date for a major that isn't true if the major does not yet have an LTS release.
Reacted by Aviv Keller, Jordan Harband and Claudio Wunder
Activity
targos commentedon Oct 28, 2025
This is a bug with the website. The first v24 LTS will be v24.11.0 (to be released today)
aduh95 commentedon Oct 28, 2025
Duplicate of #7153?
MikeMcC399 commentedon Oct 28, 2025
@aduh95
Thanks for alerting me to this issue! I deleted my comment in nodejs/node#60414 to avoid any confusion (it was already set to off-topic).
bmuenzenmeyer commentedon Oct 28, 2025
As of right now, the website is extremely data-driven, and we have found a number of places where missing data (ie: missing release overlaps, postponed or faulty releases, etc.) cause outages, only for it to correct once backing data is available.
Examples: #8217 and #8248
We should look for ways to hot-wire the behavior, such as a site.json override that allows us to force through LTS, Latest values.
Anything we do would impose it's own temporal constraints...to add and then remove as releases become available.
targos commentedon Oct 28, 2025
I've said this several times but it seems my comment is always ignored: the source of truth is https://nodejs.org/download/release/index.json. You can stay data-driven if you use that.
bmuenzenmeyer commentedon Oct 28, 2025
fair - for what it's worth, we use https://github.com/cutenode/nodevu/tree/main/core - i dont recall the origin of that decision. I am we can get to the bottom of it
aduh95 commentedon Oct 28, 2025
In particular,
curl https://nodejs.org/download/release/index.json | jq firstalways returns the latest Current, andcurl https://nodejs.org/download/release/index.json | jq 'map(select(.lts)) | first'always returns the latest LTS.bmuenzenmeyer commentedon Oct 28, 2025
It's one of those unfortunate types of issues that is wrong for a very short amount of time, but when naturally lots of eyeballs are drawn to the site.
I started looking into this. There are some reasons to use the nodevu logic. I think one solve would be to cross-reference it with the index.json to never OVERPROMISE release information that should be present based on a simple date comparison
MattIPv4 commentedon Oct 28, 2025
What do we actually need nodevu's additional support data for? I am very much in favor of just relying on our our dist file with the LTS flag it has?
bmuenzenmeyer commentedon Oct 28, 2025
I didn't look too close at the downstream usages, but it has a lot of date logic:
10 remaining items
MattIPv4 commentedon Oct 29, 2025
That is going to rather complicate things I suspect, needing to use the release schedule for some bits of support status but not others...
bmuenzenmeyer commentedon Oct 29, 2025
i started a branch to coalesce the two data sources together, but it still needs a lot of work and tests
AugustinMauroy commentedon Oct 29, 2025
we need date to know the Current version
Here a small script that I had used to know what happened so not the website code
aduh95 commentedon Oct 29, 2025
No you don't, the latest current is always the very first item in index.json
bmuenzenmeyer commentedon Oct 29, 2025
that's an interesting API contract 😅
ljharb commentedon Oct 30, 2025
I mean you can use semver sort if you don't want to depend on that, it's not a hard problem to find the latest version of something :-)
aduh95 commentedon Oct 30, 2025
That's how the
index.jsonis generated: https://github.com/nodejs/nodejs-dist-indexer/blob/caaf5af34214355494d43f8f089d3f4b0afbad20/src/dist-indexer.js#L590Anyway, my point is that comparing dates should only be used to report EOL status, otherwise it should be irrelevant.
AugustinMauroy commentedon Oct 30, 2025
Do we revalidate index.json ? If yes we can just add new propriety for EOL on it.
bnb commentedon Oct 30, 2025
Totally makes sense that there’s some drift here with these two sources and index.json should be prioritized. Probably worth looking at automating updating Scheudle.json since I know I’m not the only one relying on it :)
That said, totally agree about index.json being prioritized. In theory, should be pretty easy to check the data and see if index.json is more up to date and use that instead once we have that data - this is the exact kind of API smoothness I built nodevu to provide.
I’m about to get on a ~9 hour flight home from SFO, should be able to get a PR up in that time. Will reference this issue from it, should be a seamless fix for the website once published.
ovflowd commentedon Dec 30, 2025
Hey @bnb friendly ping/bump on this ❤️
/download/currentbroken #8786MattIPv4 commentedon Apr 1, 2026
FYI, we hit this again in #8766. I've got a fix on our end up in #8787 to manually check the LTS status of the most recent release for each major. I do still agree with what has been said here before that this should really be something that nodevu does, where it doesn't report an LTS support date for a major that isn't true if the major does not yet have an LTS release.