---
title: "Node.js 24 is here: what a Vue project needs to know · vuejs.school"
description: "Node 24.0.0 shipped on 6 May with V8 13.6, npm 11 and a stable permission flag. What it changes for a Vite and Vue project, and when to move production."
canonical_url: "https://vuejs.school/community/blog/node-24-for-vue-developers"
meta:
  "og:description": "Node 24.0.0 shipped on 6 May with V8 13.6, npm 11 and a stable permission flag. What it changes for a Vite and Vue project, and when to move production."
  "og:image": "https://vuejs.school/_og/d/a_~Tm9kZS5qcyAyNCBpcyBoZXJlOiB3aGF0IGEgVnVlIHByb2plY3QgbmVlZHMgdG8ga25vdyDCtyB2dWVqcy5zY2hvb2w%2Cc_OgCard.takumi%2Ctitle_~Tm9kZS5qcyAyNCBpcyBoZXJlOiB3aGF0IGEgVnVlIHByb2plY3QgbmVlZHMgdG8ga25vdw%2Cdescription_~Tm9kZSAyNC4wLjAgc2hpcHBlZCBvbiA2IE1heSB3aXRoIFY4IDEzLjYsIG5wbSAxMSBhbmQgYSBzdGFibGUgcGVybWlzc2lvbiBmbGFnLiBXaGF0IGl0IGNoYW5nZXMgZm9yIGEgVml0ZSBhbmQgVnVlIHByb2plY3QsIGFuZCB3aGVuIHRvIG1vdmUgcHJvZHVjdGlvbi4%2Ceyebrow_~UmVsZWFzZSBub3RlcyDCtyA2IG1pbiByZWFk%2Ctint_sand%2Cp_Ii9jb21tdW5pdHkvYmxvZy9ub2RlLTI0LWZvci12dWUtZGV2ZWxvcGVycyI%2Cs_JNHLhpDJ2x024Lbi.png"
  "og:image:alt": "Node.js 24 is here: what a Vue project needs to know · vuejs.school"
  "og:image:height": "600"
  "og:image:type": image/png
  "og:image:width": "1200"
  "og:title": "Node.js 24 is here: what a Vue project needs to know · vuejs.school"
  "twitter:image": "https://vuejs.school/_og/d/a_~Tm9kZS5qcyAyNCBpcyBoZXJlOiB3aGF0IGEgVnVlIHByb2plY3QgbmVlZHMgdG8ga25vdyDCtyB2dWVqcy5zY2hvb2w%2Cc_OgCard.takumi%2Ctitle_~Tm9kZS5qcyAyNCBpcyBoZXJlOiB3aGF0IGEgVnVlIHByb2plY3QgbmVlZHMgdG8ga25vdw%2Cdescription_~Tm9kZSAyNC4wLjAgc2hpcHBlZCBvbiA2IE1heSB3aXRoIFY4IDEzLjYsIG5wbSAxMSBhbmQgYSBzdGFibGUgcGVybWlzc2lvbiBmbGFnLiBXaGF0IGl0IGNoYW5nZXMgZm9yIGEgVml0ZSBhbmQgVnVlIHByb2plY3QsIGFuZCB3aGVuIHRvIG1vdmUgcHJvZHVjdGlvbi4%2Ceyebrow_~UmVsZWFzZSBub3RlcyDCtyA2IG1pbiByZWFk%2Ctint_sand%2Cp_Ii9jb21tdW5pdHkvYmxvZy9ub2RlLTI0LWZvci12dWUtZGV2ZWxvcGVycyI%2Cs_JNHLhpDJ2x024Lbi.png"
  "twitter:image:alt": "Node.js 24 is here: what a Vue project needs to know · vuejs.school"
---

> Index of every page on this site: [llms.txt](https://vuejs.school/llms.txt)

## What shipped in Node 24.0.0

The release post lists these notable changes:

- V8 13.6, which brings `Float16Array`, explicit resource management (the `using` declaration), `RegExp.escape`, WebAssembly Memory64 and `Error.isError`.
- npm 11.
- `AsyncLocalStorage` now uses `AsyncContextFrame` by default, which the post describes as a more efficient implementation of asynchronous context tracking.
- `URLPattern` is a global, so you no longer import it.
- The permission model flag is now `--permission` instead of `--experimental-permission`, a change the post ties to its increasing stability.
- The test runner waits for subtests automatically, so you no longer `await` each `t.test()` call.
- Undici 7, the library behind the global `fetch`.
- On Windows, building Node itself now requires ClangCL; MSVC support was removed. This only affects people compiling Node from source.

For a Vue project, two of those touch daily work: npm 11 and `URLPattern`.

npm 11 is what `npm install` now runs. Its own `engines` field is `^20.17.0 || >=22.9.0`. That does not affect anyone on Node 24, but if your team pins npm 11 for everyone, a colleague on Node 20.10 will be told to upgrade.

You can start using `URLPattern` straight away, in server code or in tests. It matches URLs the way a router matches paths:

```
const pattern = new URLPattern({ pathname: '/users/:id' })
const match = pattern.exec('https://example.com/users/42')
console.log(match?.pathname.groups.id) // "42"
```

`exec()` returns `null` for a URL that does not match, hence `match?.`.

## Check your scripts for deprecated and removed APIs

The release post also lists runtime deprecations and removals. A runtime deprecation still works but prints a `DeprecationWarning` when the code runs. A removal means the API is gone: calling a removed function throws a `TypeError`, and a removed property reads as `undefined`. The ones most likely to appear in a front-end project's scripts, build plugins or tests:

- `url.parse()` is now a runtime deprecation. Use the WHATWG `URL` class instead.
- `SlowBuffer` is a runtime deprecation; use `Buffer.allocUnsafeSlow()`. Node 24.0.0 removed it too early and broke `jsonwebtoken` through its dependencies; 24.0.1 (8 May) puts it back, so skip 24.0.0.
- `tls.createSecurePair` is removed.
- `dirent.path` is removed; read `dirent.parentPath` instead.
- The `fs.F_OK`, `fs.R_OK`, `fs.W_OK` and `fs.X_OK` constants are runtime deprecated in favour of `fs.constants`.

You are most likely to meet `url.parse()`, because it sits in a decade of copy-pasted scripts. The replacement needs a base URL when the input is a bare path:

*scripts/check-links.mjs**Breaks***

```
import { parse } from 'node:url'

const { pathname } = parse(link)
```

*scripts/check-links.mjs**Works***

```
const { pathname } = new URL(link, 'https://example.com')
```

Without the second argument, `new URL('/guide/')` throws `TypeError: Invalid URL`. Any base works when you only read `pathname`.

To find the callers, run `NODE_OPTIONS=--trace-deprecation npm run build` on Node 24. Each warning names the API, and the stack trace under it shows which file called it. If the caller is your own script, each fix above is one line. If it is a dependency, upgrade it or file an issue. One exception: `url.parse()` only warns when your own code calls it ([DEP0169](https://nodejs.org/docs/latest-v24.x/api/deprecations.html#dep0169-insecure-urlparse)), so a dependency that still uses it stays silent.

## `require()` can load ES modules without a flag

Node has two module systems: CommonJS (`require()` and `module.exports`) and ES modules (`import` and `export`). Loading an ES module with `require()` is not in the release post, because the work landed in earlier releases. The [modules documentation](https://nodejs.org/docs/latest-v24.x/api/modules.html#loading-ecmascript-modules-using-require) records three steps:

- Added behind the `--experimental-require-module` flag in 22.0 and 20.17.
- No flag needed from 23.0, 22.12 and 20.19.
- No experimental warning from 23.5, 22.13 and 20.19.

Node 24 inherits all of that, so a plain `require()` of an ES module works with no flag and no warning. The docs still mark it as a release candidate, the last stage before stable, and it has one limit: a module with top-level `await` cannot be required (`require()` throws `ERR_REQUIRE_ASYNC_MODULE`), so load that one with `import()`.

This matters because more packages now ship as ES modules only (VueUse 13, released in March, is one), and a CommonJS config file or old build script can now load them with `require()` instead of a dynamic `import()`. If your project still has a `postcss.config.js` or a `tailwind.config.js` in CommonJS form, the pressure to convert it has dropped.

## Vite 6 and Vitest 3 accept Node 24

Vite 6.3 is the current minor (6.3.0 on 16 April, 6.3.5 on 5 May). The [Vite 6 guide](https://v6.vite.dev/guide/) says "Vite requires Node.js version 18+ or 20+", and the package's `engines` field is `^18.0.0 || ^20.0.0 || >=22.0.0`. Node 24 satisfies `>=22.0.0`, so `npm install` does not complain. Vitest 3.1 declares the same range. A create-vue project needs no change.

Accepted is not the same as tested: Vite 6.3.5 and Vitest 3.1.3 run their own CI on Node 18, 20 and 22, not 24. Your build and tests are the real check, and the CI matrix below runs them.

## Keep production on Node 22 until October

Until then, 24 takes most non-breaking changes that land on Node's main branch, with new features every few weeks. That is what you want on a laptop and not what you want on a server, where an Active LTS line takes only changes the Release team has judged stable. A hosting platform may not offer 24 at all yet. For a static Vue site, "production" is just the build step, so keeping it on 22 costs nothing.

Node 18 reached end of life on 30 April 2025 and gets no more fixes. If a machine or a CI image still runs 18, this is the week to move it to 22.

## Pin the version with `.nvmrc` and `engines`

Pin the version so nobody has to remember it. A `.nvmrc` file tells `nvm` and `fnm` which version to use, and `engine-strict` makes npm refuse to install when the running Node is outside the `engines` range in `package.json`:

```
echo "22" > .nvmrc
echo "engine-strict=true" >> .npmrc
```

*package.json*

```
{
  "engines": {
    "node": ">=22.12.0"
  }
}
```

The floor is 22.12 rather than 22.0 because that is the first 22 release where `require()` of ES modules works without a flag, so every machine that passes the check behaves the same way around ESM-only packages. The range is open at the top, so Node 24 passes too.

## Test on Node 22 and 24 in CI

Run the test suite and the build on both lines. When the 24 job goes red and the 22 job stays green, you learn about the problem before a user does.

*.github/workflows/ci.yml*

```
name: CI
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node: [22, 24]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
          cache: npm
      - run: npm ci
      - run: npx vitest --run
      - run: npm run build
```

`node-version: 24` matches any 24.x, so patch releases need no edit. Add `check-latest: true` under `with:` if every run must use the newest patch rather than one cached on the runner. In October, when 24 becomes LTS, swap the roles: 24 goes into `.nvmrc` and 22 stays in the matrix until you no longer deploy to it.

**Check it stuck**3 questions from the Environment variables, builds and deployment quiz.

[**Practice now**](https://vuejs.school/learn/tooling/environment-variables-and-deployment?tab=quiz)

**Was this helpful?**

## **Keep reading**

[Tutorial · 8 min read**Editor and Vue DevTools setup in 2026**](https://vuejs.school/community/blog/editor-and-vue-devtools-setup-in-2026) [Release notes · 6 min read**Rolldown 1.0: the bundler under Vite 8 is stable**](https://vuejs.school/community/blog/rolldown-1-0-the-bundler-under-vite-8-is-stable)

```json
{"@context":"https://schema.org","@graph":[{"@id":"https://vuejs.school/#website","@type":"WebSite","description":"A free AI-instructed school for Vue.js. Short tutorials, runnable code and quizzes that adapt to you.","name":"vuejs.school","url":"https://vuejs.school/","publisher":{"@id":"https://vuejs.school/#identity"}},{"@id":"https://vuejs.school/community/blog/node-24-for-vue-developers#webpage","@type":"WebPage","dateModified":"2026-10-27T19:31:40.253Z","datePublished":"2025-05-08","description":"Node 24.0.0 shipped on 6 May with V8 13.6, npm 11 and a stable permission flag. What it changes for a Vite and Vue project, and when to move production.","name":"Node.js 24 is here: what a Vue project needs to know","url":"https://vuejs.school/community/blog/node-24-for-vue-developers","breadcrumb":{"@id":"https://vuejs.school/community/blog/node-24-for-vue-developers#breadcrumb"},"isPartOf":{"@id":"https://vuejs.school/#website"},"potentialAction":[{"@type":"ReadAction","target":["https://vuejs.school/community/blog/node-24-for-vue-developers"]}],"primaryImageOfPage":{"@id":"https://vuejs.school/#logo"}},{"@id":"https://vuejs.school/#identity","@type":"Organization","description":"A free AI-instructed school for Vue.js. Short tutorials, runnable code and quizzes that adapt to you.","name":"vuejs.school","url":"https://vuejs.school","logo":{"@id":"https://vuejs.school/#logo"}},{"@id":"https://vuejs.school/community/blog/node-24-for-vue-developers#article","dateModified":"2026-10-27T19:31:40.253Z","datePublished":"2025-05-08","description":"Node 24.0.0 shipped on 6 May with V8 13.6, npm 11 and a stable permission flag. What it changes for a Vite and Vue project, and when to move production.","headline":"Node.js 24 is here: what a Vue project needs to know","inLanguage":"en","isAccessibleForFree":true,"thumbnailUrl":"https://vuejs.school/_og/d/a_~Tm9kZS5qcyAyNCBpcyBoZXJlOiB3aGF0IGEgVnVlIHByb2plY3QgbmVlZHMgdG8ga25vdyDCtyB2dWVqcy5zY2hvb2w%2Cc_OgCard.takumi%2Ctitle_~Tm9kZS5qcyAyNCBpcyBoZXJlOiB3aGF0IGEgVnVlIHByb2plY3QgbmVlZHMgdG8ga25vdw%2Cdescription_~Tm9kZSAyNC4wLjAgc2hpcHBlZCBvbiA2IE1heSB3aXRoIFY4IDEzLjYsIG5wbSAxMSBhbmQgYSBzdGFibGUgcGVybWlzc2lvbiBmbGFnLiBXaGF0IGl0IGNoYW5nZXMgZm9yIGEgVml0ZSBhbmQgVnVlIHByb2plY3QsIGFuZCB3aGVuIHRvIG1vdmUgcHJvZHVjdGlvbi4%2Ceyebrow_~UmVsZWFzZSBub3RlcyDCtyA2IG1pbiByZWFk%2Ctint_sand%2Cp_Ii9jb21tdW5pdHkvYmxvZy9ub2RlLTI0LWZvci12dWUtZGV2ZWxvcGVycyI%2Cs_JNHLhpDJ2x024Lbi.png","@type":["Article","BlogPosting"],"articleSection":["Release notes"],"author":{"@id":"https://vuejs.school/#identity"},"image":{"@id":"https://vuejs.school/#/schema/image/1"},"isPartOf":{"@id":"https://vuejs.school/community/blog/node-24-for-vue-developers#webpage"},"mainEntityOfPage":{"@id":"https://vuejs.school/community/blog/node-24-for-vue-developers#webpage"},"publisher":{"@id":"https://vuejs.school/#identity"}},{"@id":"https://vuejs.school/community/blog/node-24-for-vue-developers#breadcrumb","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","name":"Blog","item":"https://vuejs.school/community/blog","position":1},{"@type":"ListItem","name":"Node.js 24 is here: what a Vue project needs to know","position":2}]},{"@id":"https://vuejs.school/#logo","@type":"ImageObject","caption":"vuejs.school","contentUrl":"https://vuejs.school/apple-touch-icon.png","inLanguage":"en","url":"https://vuejs.school/apple-touch-icon.png"},{"@id":"https://vuejs.school/#/schema/image/1","@type":"ImageObject","contentUrl":"https://vuejs.school/_og/d/a_~Tm9kZS5qcyAyNCBpcyBoZXJlOiB3aGF0IGEgVnVlIHByb2plY3QgbmVlZHMgdG8ga25vdyDCtyB2dWVqcy5zY2hvb2w%2Cc_OgCard.takumi%2Ctitle_~Tm9kZS5qcyAyNCBpcyBoZXJlOiB3aGF0IGEgVnVlIHByb2plY3QgbmVlZHMgdG8ga25vdw%2Cdescription_~Tm9kZSAyNC4wLjAgc2hpcHBlZCBvbiA2IE1heSB3aXRoIFY4IDEzLjYsIG5wbSAxMSBhbmQgYSBzdGFibGUgcGVybWlzc2lvbiBmbGFnLiBXaGF0IGl0IGNoYW5nZXMgZm9yIGEgVml0ZSBhbmQgVnVlIHByb2plY3QsIGFuZCB3aGVuIHRvIG1vdmUgcHJvZHVjdGlvbi4%2Ceyebrow_~UmVsZWFzZSBub3RlcyDCtyA2IG1pbiByZWFk%2Ctint_sand%2Cp_Ii9jb21tdW5pdHkvYmxvZy9ub2RlLTI0LWZvci12dWUtZGV2ZWxvcGVycyI%2Cs_JNHLhpDJ2x024Lbi.png","inLanguage":"en","url":"https://vuejs.school/_og/d/a_~Tm9kZS5qcyAyNCBpcyBoZXJlOiB3aGF0IGEgVnVlIHByb2plY3QgbmVlZHMgdG8ga25vdyDCtyB2dWVqcy5zY2hvb2w%2Cc_OgCard.takumi%2Ctitle_~Tm9kZS5qcyAyNCBpcyBoZXJlOiB3aGF0IGEgVnVlIHByb2plY3QgbmVlZHMgdG8ga25vdw%2Cdescription_~Tm9kZSAyNC4wLjAgc2hpcHBlZCBvbiA2IE1heSB3aXRoIFY4IDEzLjYsIG5wbSAxMSBhbmQgYSBzdGFibGUgcGVybWlzc2lvbiBmbGFnLiBXaGF0IGl0IGNoYW5nZXMgZm9yIGEgVml0ZSBhbmQgVnVlIHByb2plY3QsIGFuZCB3aGVuIHRvIG1vdmUgcHJvZHVjdGlvbi4%2Ceyebrow_~UmVsZWFzZSBub3RlcyDCtyA2IG1pbiByZWFk%2Ctint_sand%2Cp_Ii9jb21tdW5pdHkvYmxvZy9ub2RlLTI0LWZvci12dWUtZGV2ZWxvcGVycyI%2Cs_JNHLhpDJ2x024Lbi.png"}]}
```