Skip to content

Building with a non-standard NODE_ENV emits the dev bootstrap (import('/@vite/client'), CSS as module imports) since 2.63.1 #16008

Closed

Description

@p-c-h-b

Describe the bug

Starting with @sveltejs/kit 2.63.1 (still present in 2.64.0; 2.63.0 is fine), building with NODE_ENV set to a non-standard value (anything other than production, e.g. NODE_ENV=staging vite build) produces an adapter-static fallback page that contains the dev-mode bootstrap: the init script eagerly does import('/@vite/client') and imports the route CSS files as JS modules.

In the generated .svelte-kit/output/server/index.js of 2.63.1 the DEV guard from src/runtime/server/page/render.js (${DEV ? import('${paths.base}/@vite/client') : ''}) is constant-folded to true, so the fallback HTML ships with:

import('/@vite/client')

With 2.63.0 and the identical project + command, the guard folds to false and the fallback is clean.

At runtime in a deployed SPA this means:

  • /@vite/client 404s (or worse, gets served the HTML fallback by an SPA-routing server, producing Failed to load module script: ... MIME type of "text/html"),
  • node CSS is fetched as module scripts (... MIME type of "text/css"),
  • the dynamic import error fires on every page load, so apps with stale-deploy reload guards go into a reload loop.

This took down our CI's production-build e2e suite when Dependabot bumped 2.63.0 -> 2.64.0 (we build a "preflight" flavor with NODE_ENV=preflight). vite dev and NODE_ENV=production builds are unaffected, which makes it easy to miss.

I realize setting a custom NODE_ENV during build is unusual, but 2.63.0 and earlier handled it correctly (the server render's DEV resolved to false for any build), and the failure mode is silent at build time and total at runtime, so flagging it as a regression. Suspects in the 2.63.0...2.63.1 range would be the $app/env / explicit-env work (#15953 / #15971 / #15980), which touched how esm-env ends up resolved in the server build.

Reproduction

Four files (svelte 5.55.9, vite 7.3.5, adapter-static 3.0.10):

// package.json
{
  "name": "kit-css-repro",
  "private": true,
  "type": "module",
  "scripts": { "build": "vite build" },
  "devDependencies": {
    "@sveltejs/adapter-static": "3.0.10",
    "@sveltejs/kit": "2.63.1",
    "@sveltejs/vite-plugin-svelte": "6.2.4",
    "svelte": "5.55.9",
    "vite": "7.3.5"
  }
}
// svelte.config.js
import adapter from '@sveltejs/adapter-static';
export default { kit: { adapter: adapter({ fallback: 'index.html' }) } };
// vite.config.js
import { sveltekit } from '@sveltejs/kit/vite';
export default { plugins: [sveltekit()] };
// src/routes/+layout.ts
export const ssr = false;
export const prerender = false;

plus any trivial src/routes/+layout.svelte / +page.svelte (with a <style> block to see the CSS-as-module imports) and the default src/app.html.

NODE_ENV=staging npm run build
grep -c '@vite/client' build/index.html   # 2.63.1 / 2.64.0 -> 1, 2.63.0 -> 0

Same result with any NODE_ENV other than production (we hit it with preflight). With NODE_ENV=production or unset, the output is clean on all versions.

Logs

Browser console against the deployed 2.63.1+ build:

Failed to load module script: Expected a JavaScript-or-Wasm module script but the server
responded with a MIME type of "text/css". Strict MIME type checking is enforced for
module scripts per HTML spec.
GET https://host/@vite/client 404

System Info

@sveltejs/kit: 2.63.1 / 2.64.0 (broken), 2.63.0 (ok)
@sveltejs/adapter-static: 3.0.10
@sveltejs/vite-plugin-svelte: 6.2.4
svelte: 5.55.9
vite: 7.3.5
node: 24.x

Severity

serious, but I can work around it (pinned to 2.63.0)

Activity

  1. Rich-Harris commented on Jun 10, 2026

    @Rich-Harris
    Member

    @teemingc looks like this is caused by #15971 — I think we need to go back to the import.meta.hot trick, even though it means having to be careful about using it in all the places it's needed.

    I think we would probably need this anyway, as I suspect the import(...) approach is racy (though in practice I would be surprised if something that needed the client managed to load before the client did)

  2. added theissue type on Jun 12, 2026
  3. teemingc commented on Jun 12, 2026

    @teemingc
    Member

    Yeah, the DEV check was wrong too. I should have used __SVELTEKIT_DEV__ which is purely for checking Vite dev/build and not related to NODE_ENV

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

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions