Skip to content

Node 24.x not yet marked as LTS ("Krypton") in index.json (website lists v24.10.0 as Latest LTS) #8277

Closed
1 of 1 issue completed

Description

@MinaFayez9

Version

Not applicable – issue concerns Node.js distribution metadata, not runtime behavior.

Platform

All platforms (observed on Windows, but affects all because index.json is global).

Subsystem

Release / Distribution metadata

What steps will reproduce the bug?

  1. Visit https://nodejs.org/dist/index.json
  2. Search for any entries for version v24.x.x
    → all of them have "lts": false.
  3. Visit https://nodejs.org – it lists v24.10.0 as “Latest LTS”.
  4. 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").

Additional information

Date checked: 2025-10-28

Example entry from https://nodejs.org/dist/index.json:
{
"version": "v24.10.0",
"date": "2025-10-14",
"lts": false
}

Expected:
{
"version": "v24.10.0",
"date": "2025-10-14",
"lts": "Krypton"
}

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 🙏

Activity

  1. targos commented on Oct 28, 2025

    @targos
    Member

    This is a bug with the website. The first v24 LTS will be v24.11.0 (to be released today)

  2. transferred this issue fromnodejs/nodeon Oct 28, 2025
  3. aduh95 commented on Oct 28, 2025

    @aduh95
    Contributor

    Duplicate of #7153?

  4. MikeMcC399 commented on Oct 28, 2025

    @MikeMcC399
    Contributor

    @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).

  5. bmuenzenmeyer commented on Oct 28, 2025

    @bmuenzenmeyer
    Contributor

    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.

  6. targos commented on Oct 28, 2025

    @targos
    Member

    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.

  7. bmuenzenmeyer commented on Oct 28, 2025

    @bmuenzenmeyer
    Contributor

    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

  8. aduh95 commented on Oct 28, 2025

    @aduh95
    Contributor

    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.

  9. bmuenzenmeyer commented on Oct 28, 2025

    @bmuenzenmeyer
    Contributor

    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

  10. MattIPv4 commented on Oct 28, 2025

    @MattIPv4
    Member

    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?

  11. bmuenzenmeyer commented on Oct 28, 2025

    @bmuenzenmeyer
    Contributor

    I didn't look too close at the downstream usages, but it has a lot of date logic:

        const support = {
          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 Schedule
        const status = getNodeReleaseStatus(new Date(), support);
    
        const minorVersions = 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}`,
        }));
  12. 10 remaining items

  13. MattIPv4 commented on Oct 29, 2025

    @MattIPv4
    Member

    That is going to rather complicate things I suspect, needing to use the release schedule for some bits of support status but not others...

  14. bmuenzenmeyer commented on Oct 29, 2025

    @bmuenzenmeyer
    Contributor

    i started a branch to coalesce the two data sources together, but it still needs a lot of work and tests

  15. AugustinMauroy commented on Oct 29, 2025

    @AugustinMauroy
    Member

    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

    import { major } from '@vltpkg/semver';
    
    const INDEX_LINK = "https://nodejs.org/download/release/index.json";
    const SCHEDULE_LINK = "https://raw.githubusercontent.com/nodejs/Release/main/schedule.json";
    
    const releasesData = await fetch(INDEX_LINK).then(res => res.json());
    const scheduleData = await fetch(SCHEDULE_LINK).then(res => res.json());
    
    const getLatestLTS = (releases) => releases.find(release => release.lts !== false);
    const getLatestCurrent = (releases, schedule) => {
        const today = new Date();
        let currentMajor = null;
        let latestStartTime = -Infinity;
    
        for (const [key, info] of Object.entries(schedule)) {
            if (!info || !info.start) continue;
            const start = new Date(info.start);
            const end = info.end ? new Date(info.end) : null;
            if (isNaN(start)) continue;
    
            // Consider schedule entries that have started and not yet ended
            if (start <= today && (!end || today < end)) {
                const startTime = 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 release
        if (!currentMajor) {
            const nonLTS = releases.filter(r => r.lts === false);
            if (!nonLTS.length) return null;
            return nonLTS.sort((a, b) => new Date(b.date) - new Date(a.date))[0];
        }
    
        // find releases matching the major and return the most recently published one
        const candidates = releases.filter(r => major(r.version) === currentMajor);
        if (!candidates.length) return null;
        return candidates.sort((a, b) => new Date(b.date) - new Date(a.date))[0];
    }
    const getLTS = (releases) => 
        releases
        .filter(item => item.lts !== false)
        .reduce((acc, release) => {
            const majorVersion = major(release.version);
            if (!acc.find(item => major(item.version) === majorVersion)) {
                acc.push(release);
            }
            return acc;
        }, []);
    const getCurrent = (releases, schedule) => {
        const today = new Date();
    
        const currentMajors = Object.entries(schedule)
            .filter(([key, info]) => info && info.start && !isNaN(new Date(info.start)))
            .filter(([key, info]) => {
                const start = new Date(info.start);
                const end = info.end ? new Date(info.end) : null;
                return start <= today && (!end || today < end);
            })
            .map(([key]) => parseInt(String(key).replace(/^v/, ''), 10))
            .filter(n => !isNaN(n));
    
        if (!currentMajors.length) return [];
    
        const majorsSet = new Set(currentMajors);
    
        return releases
            .filter(r => majorsSet.has(major(r.version)))
            .sort((a, b) => {
                const ma = major(a.version);
                const mb = major(b.version);
                if (ma !== mb) return mb - ma; // higher major first
                return new Date(b.date) - new Date(a.date); // newer first within same major
            })
            .reduce((acc, release) => {
                const majorVersion = major(release.version);
                if (!acc.find(item => major(item.version) === majorVersion)) {
                    acc.push(release);
                }
                return acc;
            }, [])
            .filter(r => r.lts === false);
    };
  16. aduh95 commented on Oct 29, 2025

    @aduh95
    Contributor

    we need date to know the Current version

    No you don't, the latest current is always the very first item in index.json

  17. bmuenzenmeyer commented on Oct 29, 2025

    @bmuenzenmeyer
    Contributor

    we need date to know the Current version

    No you don't, the latest current is always the very first item in index.json

    that's an interesting API contract 😅

  18. ljharb commented on Oct 30, 2025

    @ljharb
    SponsorMember

    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 :-)

  19. aduh95 commented on Oct 30, 2025

    @aduh95
    Contributor

    That's how the index.json is generated: https://github.com/nodejs/nodejs-dist-indexer/blob/caaf5af34214355494d43f8f089d3f4b0afbad20/src/dist-indexer.js#L590

    Anyway, my point is that comparing dates should only be used to report EOL status, otherwise it should be irrelevant.

  20. AugustinMauroy commented on Oct 30, 2025

    @AugustinMauroy
    Member

    Anyway, my point is that comparing dates should only be used to report EOL status, otherwise it should be irrelevant.

    Do we revalidate index.json ? If yes we can just add new propriety for EOL on it.

  21. bnb commented on Oct 30, 2025

    @bnb
    Contributor

    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.

  22. ovflowd commented on Dec 30, 2025

    @ovflowd
    Member

    Hey @bnb friendly ping/bump on this ❤️

  23. deleted a comment from on Mar 26, 2026
  24. MattIPv4 commented on Apr 1, 2026

    @MattIPv4
    Member

    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.

  25. moved this from 📋 Backlog to ✅ Done in Node.js Websiteon Apr 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions