Skip to content

Instantly share code, notes, and snippets.

@yanneves
Last active May 20, 2026 10:50
Show Gist options
  • Select an option

  • Save yanneves/d6613e0e035caefa8bbb8abcf9c01fc3 to your computer and use it in GitHub Desktop.

Select an option

Save yanneves/d6613e0e035caefa8bbb8abcf9c01fc3 to your computer and use it in GitHub Desktop.
Storybook Dependency Resolution Bug Report (AI-assisted analysis)

Storybook Dependency Resolution Bug Report

Date: 2026-05-20
Branch: release/dashboard-alpha
Affected app: apps/dashboard (Storybook via @storybook/sveltekit)


Summary

Storybook fails to start due to a version mismatch between @sveltejs/vite-plugin-svelte at the npm workspace root and the version expected by the dashboard app and Storybook itself. npm's hoisting algorithm resolves an incompatible older version (6.x) to the root node_modules, while the apps use a local override (7.x). Storybook's deep dependency chain resolves the root version, not the workspace-local one, causing the build to crash.


Root Cause

This monorepo uses npm workspaces. apps/dashboard (and apps/client) explicitly require:

"@sveltejs/vite-plugin-svelte": "^7.1.2",
"vite": "^8.0.13"

@sveltejs/vite-plugin-svelte 7.x requires vite: "^8.0.0-beta.7 || ^8.0.0" as a peer.

However, when npm install resolves the full workspace dependency tree a self-locking cycle takes hold, driven by @sveltejs/vite-plugin-svelte-inspector@5.0.2:

@sveltejs/vite-plugin-svelte@6.2.4        (hoisted to root as a peer dep)
  └─ depends on → @sveltejs/vite-plugin-svelte-inspector@^5.0.0
                    ├─ peers against → @sveltejs/vite-plugin-svelte@^6.0.0-next.0  ← 6.x ONLY, non-optional
                    └─ peers against → vite@^6.3.0 || ^7.0.0                       ← excludes vite 8

Inspector@5 is the only package in the tree whose peer range for @sveltejs/vite-plugin-svelte excludes 7.x. Its vite@^6.3.0 || ^7.0.0 peer constraint prevents vite 8 from being hoisted to root. With root vite locked to 7.x, @sveltejs/vite-plugin-svelte@7.x (which requires vite@^8) cannot be hoisted either — so 6.2.4 wins the root slot, which keeps inspector@5 installed, which keeps the cycle closed.

npm resolves the resulting conflict by creating workspace-level overrides:

  • apps/client/node_modules/@sveltejs/vite-plugin-svelte@7.1.2 + apps/client/node_modules/vite@8.0.13
  • apps/dashboard/node_modules/@sveltejs/vite-plugin-svelte@7.1.2 + apps/dashboard/node_modules/vite@8.0.13

Why Storybook breaks: Storybook packages live under root node_modules/@storybook/.... Node's module resolution walks up from there and finds the root node_modules/@sveltejs/vite-plugin-svelte@6.2.4 — not the workspace-local 7.1.2. With vite 8.x in use (from the workspace overrides), @sveltejs/vite-plugin-svelte@6.2.4 either throws a peer validation error or behaves incorrectly against the vite 8 API, breaking the Storybook build/dev server.

Exact version deltas (broken → fixed)

Package Before (broken) After (fixed)
root node_modules/vite 7.3.1 8.0.13
root node_modules/@sveltejs/vite-plugin-svelte 6.2.4 7.1.2
apps/*/node_modules/@sveltejs/vite-plugin-svelte 7.1.2 (workspace override) (removed — root now satisfies)
apps/*/node_modules/vite 8.0.13 (workspace override) (removed — root now satisfies)

Fix

The fix ensures the root-level hoisted versions are also 7.x / vite 8.x, removing the need for workspace-level overrides. This works because @sveltejs/vite-plugin-svelte@7.x dropped @sveltejs/vite-plugin-svelte-inspector as a dependency entirely — without inspector@5 in the tree, the vite@^7 constraint is gone and npm can hoist vite 8 and vite-plugin-svelte 7 to root without conflict.

The broken state can sneak back in if a future @sveltejs/vite-plugin-svelte release reintroduces inspector (or any other package that peers against vite@<8 and @sveltejs/vite-plugin-svelte@^6). Before removing the Option A overrides, verify any reintroduced inspector version accepts vite@^8.

To re-apply the fix if the issue recurs:

Option A — Add an npm overrides block (recommended, permanent)

Add to the root package.json:

"overrides": {
  "@sveltejs/vite-plugin-svelte": "^7.1.2",
  "vite": "^8.0.13"
}

Then run:

npm install

This forces npm to always resolve these packages to compatible versions across the entire workspace tree, preventing the broken state from being re-introduced.

Option B — Re-run npm install with forced resolution (manual, temporary)

rm -rf node_modules package-lock.json
npm install

If the broken state re-appears in package-lock.json, check for any package that peers against @sveltejs/vite-plugin-svelte@^6.x or vite@<8 with a non-optional, non-wide range. The known historical culprit is @sveltejs/vite-plugin-svelte-inspector@5.x. Find it with:

npm ls @sveltejs/vite-plugin-svelte --all 2>/dev/null | grep -v "deduped\|UNMET"
npm ls vite --all 2>/dev/null | grep -v "deduped\|UNMET"

Option C — Pin @storybook/sveltekit (if upstream is the source)

If the bad resolution originates from a Storybook package peer-requiring an older vite-plugin-svelte, pinning Storybook versions prevents silent upgrades from re-triggering it:

"overrides": {
  "@storybook/sveltekit": "10.4.0",
  "@sveltejs/vite-plugin-svelte": "^7.1.2",
  "vite": "^8.0.13"
}

Verification

After applying the fix, confirm the correct versions are at the root:

cat node_modules/@sveltejs/vite-plugin-svelte/package.json | grep '"version"'
# should print "7.x.x"

cat node_modules/vite/package.json | grep '"version"'
# should print "8.x.x"

npm run storybook --workspace=apps/dashboard
# should start without errors

Detection Signal

If this regresses, the Storybook error will typically look like one of:

  • Error: Vite peer dependency mismatch: @sveltejs/vite-plugin-svelte requires vite@^8 but found vite@7
  • Cannot find module 'vite/...' from within @sveltejs/vite-plugin-svelte
  • Storybook builder silently using wrong vite config transforms, producing a blank/broken UI

Quick check:

node -e "console.log(require('./node_modules/@sveltejs/vite-plugin-svelte/package.json').version)"
# If this prints 6.x, the bug has returned
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment