Skip to content

Issues with Node 25 #1950

Open
Open

Description

@dodomorandi

Describe the bug
The probject experiences strange issues with Node 25. The testing environment throws an assertion and when using happy-dom as a testing environment the localStorage is an empty object.

To Reproduce
Steps to reproduce the behavior in relationship to the project itself:

  1. Install and use Node 25 (nvm can be handy)
  2. Clone the repo
  3. npm install
  4. npm run test

Expected behavior
Tests run and pass. This works flawlessly with Node 24.

Screenshots
Image

To Reproduce (2)
Steps to reproduce the (probably related) issue about localStorage from an external project:

  1. Install and use Node 25
  2. Create a dummy project installing vitest and happy-dom
  3. Create the following test file:
    // @vitest-environment happy-dom
    
    import { describe,it } from 'vitest';
    
    describe("test", () => {
      it("breaks localStorage", () => {
        window.localStorage.getItem("hello");
      })
    })
  4. Run npx vitest

Expected behavior
Tests run and pass, works with Node 24

Screenshots

Image

Device:

  • OS: Arch Linux
  • Node 25.1.0

Additional context
I cannot be sure the two noticed behavior are directly correlated, I only supposed so. If you realize the two problems are separated issues just let me know and I will split this specific issue in two.

Activity

  1. brianhelba commented on Nov 12, 2025

    @brianhelba
    Contributor

    I'm having the same issue.

    Note, a warning is also being printed prior to the localStorage.getItem is not a function error:

    (node:2282) Warning: --localstorage-file was provided without a valid path
    (Use node --trace-warnings ... to show where the warning was created)


    There's a significant change in Node 25:

    Web Storage is enabled by default

    [3312e4e946] - (SEMVER-MAJOR) src: unflag --experimental-webstorage by default (Daniel M Brasil) #57666

    Looking at the Node docs, it appears that localstorage is now available, but requires the --localstorage-file flag. I'm guessing that Node's localstorage implementation is now taking precedence over Happy DOM's polyfill.


    I enjoyed the fact that localstorage used to "just work" under Happy DOM. If necessary, I will use Vitest's execArgv config option to pass --localstorage-file into my test suite, but ideally Happy DOM could do this for me on Node 25+.

  2. brianhelba commented on Nov 12, 2025

    @brianhelba
    Contributor

    I just found vitest-dev/vitest#8757 , who is punting the issue to upstream Node (which I think is appropriate, though maybe Happy DOM is responsible too).


    In Node, it looks like v25.2 (released yesterday) contains a fix for nodejs/node#60303 . I just installed v25.2.0 and any access to localstorage now immediately fails with:

    SecurityError: Cannot initialize local storage without a --localstorage-file path

    This error is also now occurring call to window.localStorage.clear() (which previously didn't fail on v25.1).


    Per the patch in Node nodejs/node#60351 (comment), it looks like for v25.2+, a downstream needs

    function localStorageIsAvailable() {
      try {
        return typeof localStorage !== 'undefined';
      } catch {
        return false;
      }
    }

    Perhaps Happy DOM can do this, and polyfill window.localstorage with its existing implementation if Node isn't providing it (either because it's not implemented in < v25 or because it's not configured via --localstorage-file).

    If we want to get Node v25.0 and v25.1 working, an additional check might be necessary.

  3. brianhelba commented on Nov 12, 2025

    @brianhelba
    Contributor

    As a workaround for now, I added to my vitest.config.ts (using Vitest v4):

    import os from 'node:os';
    import path from 'node:path';
    import process from 'node:process';
    import { defineConfig } from 'vitest/config';
    
    export default defineConfig({
      test: {
        environment: 'happy-dom',
        execArgv: [
          '--localstorage-file',
          path.resolve(os.tmpdir(), `vitest-${process.pid}.localstorage`),
        ],
      },
    });

    My tests are passing again.

  4. added 4 commits that reference this issue on Jan 21, 2026
  5. TheJaredWilcurt commented on Feb 10, 2026

    @TheJaredWilcurt

    I will be so happy when this is fixed, been dealing with dozens of these warnings being spammed in the console since November. I'm getting this when testing Vue components that get/set localStorage (dark mode setting, etc), when testing them in Vitest/Vue-Dev-Tools/HappyDOM. Example:

    test('Loads light value from local storage', async () => {
      window.localStorage.setItem(localStorageId, '{"theme":"light"}');
      const wrapper = await setupWrapper();
    
      expect(wrapper.vm.loadData())
        .toEqual({ theme: 'light' });
    });

    Not sure if this needs fixed at the Node, Vitest, or HappyDOM level, but excited to see it fixed somewhere so the work-around won't be needed.

    • Node: 25.6.1
    • npm: 11.9.0
    • vitest: 4.0.18
    • happy-dom: 20.6.0
    • @vue/test-utils: 2.4.6
  6. r-thomson commented on Feb 10, 2026

    @r-thomson
    Contributor

    Just wanted to share the workaround I have been using with Vitest:

    export default defineConfig(({ command, mode }) => {
    	const nodeMajor = +process.versions.node.split('.')[0];
    
    	return {
    		// ...
    		test: {
    			environment: 'happy-dom',
    			execArgv: nodeMajor >= 25 ? ['--no-experimental-webstorage'] : [],
    		},
    	};
    });

    Hopefully this is helpful to someone.

  7. silverwind commented on May 7, 2026

    @silverwind
    Contributor

    Node 26 is now stable, a lot more people will start hitting this.

  8. added a commit that references this issue on Aug 31, 2026
  9. TrevorBurnham commented on Oct 17, 2026

    @TrevorBurnham
    Contributor

    For anyone still hitting this on Node 25+ with vitest: it was fixed in vitest 5.0.0 (vitest-dev/vitest#10293). The fix wasn't backported to v4, so upgrading to vitest 5 should resolve it. I think this issue can be closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions