Skip to content
Nilay Kabariya

Entry No.055·Tested·Updated ·8 min read

18 framework starters tested on Windows: what breaks

Next.js, Nuxt, Remix 3, TanStack Start, Angular, Docusaurus and 12 more, scaffolded, built and served on Windows 11. One still fails out of the box.

Verdict

15 of 18 starters work on Windows 11: 14 with no issues at all, 1 with a workaround. Every Remix 3 script still fails out of the box and works on Linux; Docusaurus's Windows build failure is fixed by SWC 1.16.21, Nuxt's Windows-only 500 is fixed in 4.6.1, and React Router's installer in 8.5.1. Three more break in ways that tutorials and CI scripts hit: Angular needs a newer Node 24, Electron Forge renamed its template, and Cloudflare's C3 can exit successfully with a broken project.

Tested on

OS
Windows 11 Pro (Linux in Docker for comparison)
Node / npm
24.14.0 / 11.9.0 (Angular also on 24.21.0)
Starters
latest versions, October 9, 2026
Contents
  1. The results01
  2. Nuxt 4.6.0: every page returns 500 (fixed in 4.6.1)02
  3. Docusaurus 3.10.2: the build failed on Windows until SWC 1.16.2103
  4. React Router 8.4.0: “Failed to install dependencies” (fixed in 8.5.1)04
  5. Angular: the CLI refuses Node 24.14.005
  6. Electron Forge: the old template name is gone06
  7. Cloudflare C3: success, with a broken project07
  8. Remix 3: “‘NODE_ENV’ is not recognized”08
  9. What I couldn’t measure fairly09
  10. How this was tested10

Most framework docs are written on a Mac, and most CI runs on Linux. So I took the official starter of 16 popular frameworks and did on Windows 11 what a new user does: scaffold it, install, build, start the dev server and open the page. The same script then ran on Linux, so a failure could be split into “broken on Windows” and “broken everywhere”.

The results

Starter Version Scaffold Build Dev server
Next.js (create-next-app) 16.4.0 ✅ ✅ ✅
Vite + React 8.3.4 ✅ ✅ ✅
Vue (create-vue) 3.5.43 ✅ ✅ ✅
Astro 7.3.8 ✅ ✅ ✅
SvelteKit (sv) 3.0.1 ✅ ✅ ✅
Nuxt 4.6.0 → 4.6.1 ✅ ✅ ❌ 500 on every page in 4.6.0, ✅ fixed in 4.6.1
Angular 22.2.2 ⚠️ refuses Node 24.14.0 ✅ ✅
React Router 8.4.0 → 8.5.1 ❌ “Failed to install dependencies” up to 8.5.0, ✅ fixed in 8.5.1 ✅ ✅
NestJS 12.1.2 ✅ ✅ ✅
Expo 57.0.27 ✅ n/a ✅ (web)
Cloudflare (C3) C3 2.73.4 ⚠️ exits 0 with a broken config in CI n/a ✅
Hono 4.13.13 ✅ ✅ ✅
Qwik 1.20.2 ✅ ✅ ✅
Docusaurus 3.10.2 ✅ ❌ native binding fails up to SWC 1.16.20, ✅ fixed in SWC 1.16.21 ✅
Electron Forge 44.7.0 ⚠️ old template name rejected n/a not tested
create-t3-app Next.js 15.5.27 ✅ ✅ ✅
TanStack Start 1.169.1 ✅ ✅ ✅
Remix 3 3.0.0 ✅ n/a ❌ ‘NODE_ENV’ is not recognized

The red rows worked on Linux with the same versions. They’re Windows bugs. The ⚠️ rows fail the same way on any OS, and they’re the kind tutorials and scripts trip over.

One detail from the green rows: create-t3-app still installs Next.js 15, not 16. Its version, 15.5.27, is the 15.x release that has the September security fixes (which Next.js versions are patched).

Nuxt 4.6.0: every page returns 500 (fixed in 4.6.1)

The scaffold and nuxt build were fine. Then npm run dev started, printed its URL, and every request failed:

[request error] [GET] /
  ✖ Error (500): Either manifest or precomputed data must be provided

It isn’t a leftover from building first: on a clean copy, with .nuxt and .output deleted and only npm run dev, the result was the same 500. On Linux the same starter served the page. It’s reported as nuxt/nuxt#36467. Nuxt 4.6.1, published on October 9, 2026 (UTC), carries the fix.

Upgrade to 4.6.1:

npm i nuxt@4.6.1

If you can’t upgrade yet, this in nuxt.config.ts fixed 4.6.0:

export default defineNuxtConfig({
  nitro: {
    externals: {
      inline: [(id: string) => id.replace(/\\/g, '/').includes('/node_modules/nuxt/dist/')],
    },
  },
  // ...the rest of your config
})

A regex version of this workaround is going around too. If you use one, the character class must contain a backslash and a slash, [\\/]. My first attempt wrote [\/], which only matches /, never matches a Windows path, and left the 500 in place.

Docusaurus 3.10.2: the build failed on Windows until SWC 1.16.21

What the failure looked like, for anyone still on an older SWC:

npm run start worked; npm run build didn’t:

[ERROR] Error: Unable to build website for locale en.
  [cause]: Error: Failed to load native binding
    Error: Cannot find module './swc-html.win32-x64-msvc.node'

That last line is misleading: the Windows package is installed. Loading it directly showed the real error. SWC 1.16 (the HTML minifier Docusaurus uses) checks the permissions of its cache folder and every folder above it, and refuses to load when any of them lets other users modify it:

SWC native addon: validate cache root ...: cache ancestor C:\: DACL grants replacement rights 0x1301bf to SID S-1-5-11

S-1-5-11 is Authenticated Users. On this machine they can modify C:\, as on many Windows installs, and that’s the default for the root of a second drive like D:. Pointing the cache somewhere else with SWC_NATIVE_BINDING_CACHE didn’t help: a folder on D: failed the same check. On Linux the build passed. The upstream report is swc-project/swc#12442. It’s closed, but the build still failed with 1.16.13, with 1.16.18 (re-checked October 11) and, re-checked on October 24, with 1.16.20, the newest release. 1.16.20 tries a third cache, in C:\ProgramData, and that fails the same check too: ProgramData cache failed: validate cache root C:\ProgramData: cache ancestor C:\: DACL grants replacement rights 0x1301bf to SID S-1-5-11. 1.16.18 adds a second cache in your user folder (.swc-cache) to fall back on, and that one fails the same check. To rule out my machine, I gave C:\ the same permissions on a clean GitHub Actions Windows runner: 1.16.13 and 1.16.18 both failed there, and 1.15.47 loaded (the test).

Update SWC to 1.16.21 or newer. In a Docusaurus project, SWC comes in through @docusaurus/core, so update it in place:

npm update @swc/core @swc/html

If you added the 1.15 overrides below earlier, remove them first, then run npm install.

If you can’t update, pin SWC back to 1.15 with npm overrides in your package.json, then reinstall:

{
  "overrides": {
    "@swc/html": "~1.15.0",
    "@swc/core": "~1.15.0"
  }
}

React Router 8.4.0: “Failed to install dependencies” (fixed in 8.5.1)

      ✔  Template copied
      ◼  Install Dependencies installing with npm...
      ▲  Oh no! Failed to install dependencies.

No error follows, even with --show-install-output. The reason is in create-react-router’s own code: it starts the installer with spawn("npm", ["install"]) and no shell. On Windows npm is npm.cmd, which Node can’t start that way:

> node -e "require('child_process').spawn('npm',['-v']).on('error',e=>console.log(e.message))"
spawn npm ENOENT

That’s also why --show-install-output shows nothing: npm never starts, so there’s no output. The scaffold itself is fine, and on Linux the same command installed normally. It was reported for 8.3.0 in remix-run/react-router#15385 and closed without a cause.

I re-tested on October 28, 2026 (Windows 11, Node 24.14.0). create-react-router@8.5.0 still failed the same way. 8.5.1 fixes it: on Windows it now runs the installer through cmd.exe /d /s /c, and the same command printed ✔ Dependencies installed, then npm run build passed with react-router 8.5.1.

Use 8.5.1 or newer, and the installer works:

npx create-react-router@latest my-app

If you already have a folder from an older version, the project is complete. Install it yourself:

cd my-app
npm install

Angular: the CLI refuses Node 24.14.0

Node.js version v24.14.0 detected.
The Angular CLI requires a minimum Node.js version of v22.22.3 or v24.15.0 or v26.0.0.

That’s not Windows-specific, but 24.14.0 is a recent LTS release, and many machines are still on it.

Update Node within the 24 line. With Node 24.21.0, ng new scaffolded the app, ng build passed and ng serve served the page.

Electron Forge: the old template name is gone

Many tutorials still use --template=vite-typescript:

✖ Resolving template: vite-typescript [FAILED: The "vite-typescript" template no longer exists. Use "--template vite --typescript" instead.]

Use the new form the error suggests:

npx create-electron-app@latest my-app --template vite --typescript

Cloudflare C3: success, with a broken project

C3 2.73.4 added a question, “Do you want to add an AGENTS.md file?”. When it runs without a terminal to ask in, which is the case in CI, scripts and AI coding agents, it stopped at that question and still exited with code 0. It had already written the files, but not the Worker’s name:

"name": "<WORKER_NAME>",

The next step fails, after your pipeline has already reported success:

X [ERROR] Processing wrangler.jsonc configuration:
  - Expected "name" to be of type string, alphanumeric and lowercase with dashes only but got "<WORKER_NAME>".

Answer the new question on the command line:

npm create cloudflare@latest my-worker -- --type hello-world --lang ts --no-deploy --no-git --no-agents

Remix 3: “‘NODE_ENV’ is not recognized”

Remix 3 scaffolds and installs fine on Windows (npx remix@latest new app). Then every script in the new project fails, because each one sets an environment variable the Linux and macOS way:

"dev": "NODE_ENV=development node --watch --import remix/node-tsx server.ts",
"start": "NODE_ENV=production node --import remix/node-tsx server.ts",
"test": "NODE_ENV=test remix test"

npm runs scripts with cmd.exe on Windows, which doesn’t understand that syntax:

'NODE_ENV' is not recognized as an internal or external command,
operable program or batch file.

npm run dev and npm test both stopped there; start and hmr use the same syntax. On GitHub’s Ubuntu runner, the same freshly generated project served the page from npm run dev and passed npm test, unchanged.

Install cross-env, which sets variables the same way on every OS, and put it in front of each script:

npm i -D cross-env
"dev": "cross-env NODE_ENV=development node --watch --import remix/node-tsx server.ts",
"start": "cross-env NODE_ENV=production node --import remix/node-tsx server.ts",
"test": "cross-env NODE_ENV=test remix test"

What I couldn’t measure fairly

  • Times and sizes. Scaffold and install times depend on the network and the npm cache, so I’ve left them out of the table. The biggest node_modules were Expo (496 MB), Next.js (390 MB) and create-t3-app (388 MB); the smallest were Hono (47 MB) and SvelteKit (73 MB).
  • Electron’s window. Opening a desktop window isn’t something a script can check, so Electron was tested up to scaffold and install.
  • My machine’s quirks. Two failures came from my setup, not the frameworks, and they aren’t in the results: Docker resolving localhost to IPv6 while some dev servers listen on IPv4 only, and an antivirus that intercepts HTTPS breaking Next.js’s Google Fonts download inside a container.

How this was tested

A Node script ran each starter’s own command in an empty folder on Windows 11 Pro, with Node 24.14.0 and npm 11.9.0, with no keyboard input (as in CI). It then ran npm install if the starter hadn’t, npm run build if the starter has one, then the dev server, and requested the page it printed. Angular was run again on Node 24.21.0. The same script ran in the official node:24 Docker image (Node 24.21.0) for the Linux comparison. Each failure was re-checked by hand before it went in, and each workaround was applied and the step re-run. Versions are whatever latest gave on October 9, 2026.

The script and the raw results are public: starters-windows in nk-repro.

— N.K., end of entry No.055

Useful? Pass it on:Post on XFollow @EmotionalMatter

Related entries

  1. No.057

    Node 26 vs Node 24: what breaks when you upgrade, tested

    Most projects move over cleanly: jsonwebtoken, bcrypt, sharp, better-sqlite3 13, tsx and Vitest all worked unchanged. What broke: Corepack and Yarn are gone (Docker builds fail with exit code 127), native modules installed under Node 24 refuse to load, fs.rmdir with recursive now throws (prisma generate with zod-prisma-types fails on the second run), and fs.W_OK disappeared without an error.

    TESTED8 minWindows
  2. No.037

    npm 12 breaking changes, tested: what actually breaks

    The headline change, install scripts blocked by default, broke puppeteer, cypress, sqlite3 and Claude Code's npm package, and silently skipped lefthook's git hooks. esbuild, bcrypt, sharp and better-sqlite3 kept working. Every install reported success, and the only sign was a warning after the summary.

    TESTED6 minWindows
  3. No.093

    Fix: bigint Failed to load bindings, pure JS will be used

    bigint: Failed to load bindings, pure JS will be used. Why npm 12 shows it on every install, whether it matters, and how to get the native build back.

    > bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)

    FIXED3 minWindows

Post card · Every Sunday

What broke this week.

One email on Sundays: the Node, TypeScript, Python and AI SDK releases that broke builds that week, each one reproduced, with a link to the fix that worked. Never shared, and you can leave any time.

— Nilay

or follow by RSSor on X

By subscribing you agree to the privacy note. One click to leave.

tip: paste the exact error text