Describe the bug
Optional chaining is removed during Vite 8 production bundling when accessing a property from an imported Svelte $state.
Example:
export const app = $state({ user: null })
Used as:
import * as h from './state.svelte.js'
h.app?.user?.name ?? 'ok'
Expected result:
The expression evaluates safely to "ok".
Actual result:
The console log throws:
TypeError: Cannot read properties of null (reading 'name')
It appears that the optional chaining is removed during bundling:
h.app?.user?.name
becomes
h.app.user.name
Reproduction
https://stackblitz.com/edit/vitejs-vite-bxd2fnks
Steps to reproduce
- Open the StackBlitz link — preview shows "Result : ok" (dev mode, works fine)
- In the StackBlitz terminal: Ctrl+C to stop the dev server
- Run: npm run build
- Run: npm run preview
- The preview now shows the production build → check browser console for TypeError
project.zip
System Info
npmPackages:
@sveltejs/vite-plugin-svelte: ^7.0.0 => 7.0.0
svelte: ^5.53.0 => 5.53.12
vite: ^8.0.0 => 8.0.0
System:
OS: Windows 11 10.0.26200
CPU: (8) x64 AMD Ryzen 7 3700U with Radeon Vega Mobile Gfx
Memory: 2.42 GB / 17.94 GB
Binaries:
Node: 24.11.1 - C:\Program Files\nodejs\node.EXE
npm: 11.6.4 - C:\Program Files\nodejs\npm.CMD
Browsers:
Chrome: 145.0.7632.161
Used Package Manager
npm
Logs
There is not error in build
npm run build
vite8-svelte5-optional-chaining-bug@1.0.0 build
vite build
(node:28) ExperimentalWarning: WASI is an experimental feature and might change at any time
(Use node --trace-warnings ... to show where the warning was created)
(node:28) ExperimentalWarning: WASI is an experimental feature and might change at any time
(Use node --trace-warnings ... to show where the warning was created)
(node:28) ExperimentalWarning: WASI is an experimental feature and might change at any time
(Use node --trace-warnings ... to show where the warning was created)
vite v8.0.0 building client environment for production...
✓ 109 modules transformed.
computing gzip size...
dist/index.html 0.34 kB │ gzip: 0.27 kB
dist/assets/index-CMMK_kCj.js 91.59 kB │ gzip: 23.84 kB
✓ built in 2.41s
~/projects/vitejs-vite-bxd2fnks 13s
❯
Validations
Describe the bug
Optional chaining is removed during Vite 8 production bundling when accessing a property from an imported Svelte
$state.Example:
export const app = $state({ user: null })Used as:
Expected result:
The expression evaluates safely to "ok".
Actual result:
The console log throws:
TypeError: Cannot read properties of null (reading 'name')
It appears that the optional chaining is removed during bundling:
h.app?.user?.namebecomes
h.app.user.nameReproduction
https://stackblitz.com/edit/vitejs-vite-bxd2fnks
Steps to reproduce
project.zip
System Info
npmPackages: @sveltejs/vite-plugin-svelte: ^7.0.0 => 7.0.0 svelte: ^5.53.0 => 5.53.12 vite: ^8.0.0 => 8.0.0 System: OS: Windows 11 10.0.26200 CPU: (8) x64 AMD Ryzen 7 3700U with Radeon Vega Mobile Gfx Memory: 2.42 GB / 17.94 GB Binaries: Node: 24.11.1 - C:\Program Files\nodejs\node.EXE npm: 11.6.4 - C:\Program Files\nodejs\npm.CMD Browsers: Chrome: 145.0.7632.161Used Package Manager
npm
Logs
There is not error in build
npm run build
(node:28) ExperimentalWarning: WASI is an experimental feature and might change at any time
(Use
node --trace-warnings ...to show where the warning was created)(node:28) ExperimentalWarning: WASI is an experimental feature and might change at any time
(Use
node --trace-warnings ...to show where the warning was created)(node:28) ExperimentalWarning: WASI is an experimental feature and might change at any time
(Use
node --trace-warnings ...to show where the warning was created)vite v8.0.0 building client environment for production...
✓ 109 modules transformed.
computing gzip size...
dist/index.html 0.34 kB │ gzip: 0.27 kB
dist/assets/index-CMMK_kCj.js 91.59 kB │ gzip: 23.84 kB
✓ built in 2.41s
~/projects/vitejs-vite-bxd2fnks 13s
❯
Validations