Bug
@phosphor-icons/react@2.1.8 fails at runtime with TypeError:
Cannot destructure 'null' as it is null when an app is bundled
by rolldown (the bundler now used by Vite 8.x). The error
originates from IconBase.es.js and prevents any icon from
rendering — the page is blank.
Confirmed in a 4-file minimal repro (no MUI, no emotion, no
app-level config): vite 8.0.16, @vitejs/plugin-react 5.2.0 (also
reproduces with 6.0.2), @phosphor-icons/react 2.1.8, react
18.3.1.
Root cause
dist/lib/IconBase.es.js chains two destructuring assignments —
both with rest patterns — into a single const:
// dist/lib/IconBase.es.js, lines 5–20
const {
alt: n,
color: r,
size: t,
weight: o,
mirrored: c,
children: i,
weights: m,
...x
} = s, {
color: d = "currentColor",
size: l,
weight: f = "regular",
mirrored: g = !1,
...w
} = e.useContext(h);
When rolldown lowers this pattern, it correctly transpiles each
rest spread into a helper call (_(obj, knownKeys)) — but in the
process emits a junk {} = null statement after the second
destructure. Excerpt from the minified output:
let l = C.useContext(ae),
{ color:u = `currentColor`, ..., mirrored:p = !1 } = l,
m = _(l, oe),
{} = null; // ← rolldown injected this; throws at runtime
Reproduces on rolldown 1.0.1 and 1.0.3. So pinning rolldown
doesn't help.
Minimal reproduction
// package.json
{
"type": "module",
"dependencies": {
"@phosphor-icons/react": "2.1.8",
"react": "18.3.1",
"react-dom": "18.3.1"
},
"devDependencies": {
"@vitejs/plugin-react": "5.2.0",
"vite": "8.0.16"
}
}
// vite.config.mts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({ plugins: [react()] });
// src/main.tsx
import { createRoot } from "react-dom/client";
import { HeartIcon } from "@phosphor-icons/react";
createRoot(document.getElementById("root")!).render(<HeartIcon
size={32} />);
<!-- index.html -->
<!DOCTYPE html>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
Run: npm install --include=optional && npx vite build && npx
vite preview → open the preview URL → blank page + the
destructure-null error in the console. Inspect the built JS
bundle and search for {}=null to see the offending statement.
Suggested fix in IconBase
Splitting the chained const into two separate declarations
avoids the rolldown bug entirely — the rest-spread pattern is
fine on its own, only the chained form trips the compiler:
// Before:
const {
alt: n, color: r, size: t, weight: o, mirrored: c, children:
i, weights: m,
...x
} = s, {
color: d = "currentColor",
size: l,
weight: f = "regular",
mirrored: g = !1,
...w
} = e.useContext(h);
// After:
const {
alt: n, color: r, size: t, weight: o, mirrored: c, children:
i, weights: m,
...x
} = s;
const {
color: d = "currentColor",
size: l,
weight: f = "regular",
mirrored: g = !1,
...w
} = e.useContext(h);
I'm running this exact change as a local yarn patch and it
produces a bundle without the {} = null statement; icons render
correctly.
Where the bug really lives
This is fundamentally a rolldown compiler bug — the original
chained destructure is valid JavaScript. I'll be filing it
upstream too. But because the Vite ecosystem is migrating to
rolldown right now (and Vite 8 is GA), any user upgrading their
Vite-based app to 8.x with @phosphor-icons/react will hit this.
Adjusting IconBase is a one-line code change for a real-world
unblock, regardless of the upstream timeline.
Environment
- @phosphor-icons/react: 2.1.8
- vite: 8.0.16
- rolldown: 1.0.1 and 1.0.3 (both reproduce)
- @vitejs/plugin-react: 5.2.0 and 6.0.2 (both reproduce)
- Node: 20.19.0
- macOS, Apple Silicon (no platform-specific element to the bug)
Bug
@phosphor-icons/react@2.1.8 fails at runtime with TypeError:
Cannot destructure 'null' as it is null when an app is bundled
by rolldown (the bundler now used by Vite 8.x). The error
originates from IconBase.es.js and prevents any icon from
rendering — the page is blank.
Confirmed in a 4-file minimal repro (no MUI, no emotion, no
app-level config): vite 8.0.16, @vitejs/plugin-react 5.2.0 (also
reproduces with 6.0.2), @phosphor-icons/react 2.1.8, react
18.3.1.
Root cause
dist/lib/IconBase.es.js chains two destructuring assignments —
both with rest patterns — into a single const:
When rolldown lowers this pattern, it correctly transpiles each
rest spread into a helper call (_(obj, knownKeys)) — but in the
process emits a junk {} = null statement after the second
destructure. Excerpt from the minified output:
Reproduces on rolldown 1.0.1 and 1.0.3. So pinning rolldown
doesn't help.
Minimal reproduction
Run: npm install --include=optional && npx vite build && npx
vite preview → open the preview URL → blank page + the
destructure-null error in the console. Inspect the built JS
bundle and search for {}=null to see the offending statement.
Suggested fix in IconBase
Splitting the chained const into two separate declarations
avoids the rolldown bug entirely — the rest-spread pattern is
fine on its own, only the chained form trips the compiler:
I'm running this exact change as a local yarn patch and it
produces a bundle without the {} = null statement; icons render
correctly.
Where the bug really lives
This is fundamentally a rolldown compiler bug — the original
chained destructure is valid JavaScript. I'll be filing it
upstream too. But because the Vite ecosystem is migrating to
rolldown right now (and Vite 8 is GA), any user upgrading their
Vite-based app to 8.x with @phosphor-icons/react will hit this.
Adjusting IconBase is a one-line code change for a real-world
unblock, regardless of the upstream timeline.
Environment