-
-
Notifications
You must be signed in to change notification settings - Fork 114
feat!: add Storybook 10 and Nuxt 4 support #981
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat!: add Storybook 10 and Nuxt 4 support #981
Conversation
- Add full compatibility with Storybook 10's ESM-only architecture
- Fix errx module MIME type error in Vite dependency optimization
- Fix Nuxt app manifest 404 errors in Storybook preview
- Update peerDependencies to require Nuxt 4.0.0+ and Storybook 10.0.0+
- Add comprehensive migration guide with step-by-step upgrade
instructions
- Enhance code documentation for ESM workarounds
BREAKING CHANGE: Requires Nuxt 4.0.0+, Storybook 10.0.0+, and Node.js
20.19+/22.12+/24+. Drops support for Nuxt 3.x and Storybook 8/9.
This message:
- ✅ Follows conventional commit format (feat:)
- ✅ Highlights the main feature (Storybook 10 & Nuxt 4 support)
- ✅ Lists key technical changes
- ✅ Includes BREAKING CHANGE: footer for major version indication
- ✅ Matches the repository's existing commit style
- ✅ Includes the Claude Code attribution as per the project's
convention
👷 Deploy request for nuxt-storybook pending review.Visit the deploys page to approve it
|
|
Hi @tobiasdiez - I took a shot at adding Storybook 10 and Nuxt 4.2 support to the package. I noticed the 3 failing integration tests had some visual difference errors. I attempted to access the report in the GitHub Action, but it looks to be password-protected. Can I run those locally and get the visual diffs? I am very curious to know what changed. The other minor detraction I made from the previous versions was using TSDown as the package bundler, in an attempt to resolve the Nuxt 4.2 compatibility issue. I look forward to any feedback you or any other maintainers may have. |
|
Cheers @akornmeier, thanks for taking on the upgrade. 🙏🏻 Out of curiosity, are there particular technical reason why the upgrade to Storybook v10 needs to be accompanied by raising the minimum supported version to Nuxt v4? While Nuxt v3 will reach EoL end of January 2026, a portion of projects might not yet have migrated to Nuxt 4. Raising the minimum supported Nuxt version would exclude those projects from benefiting of the Storybook v10 upgrade. |
Great question @rpauls-scayle, I will take a look and see if that minimum support can be relaxed back to Nuxt 3 and get back to you. Thanks for your insight! |
@rpauls-scayle - Was able to confirm that Nuxt >= v3.18.1 is compatible with the new version of Storybook. I went ahead and adjusted the Peer dependencies and updated the README.md to reflect the supported versions. Good catch, thanks! |
|
Thanks @akornmeier for taking the time to look into Nuxt 3 compatibility. |
|
Hey @chakAs3 @tobiasdiez! 👋 I've submitted a PR and would love to get your feedback on it when you have a chance. Really excited about the Thanks! |
tobiasdiez
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for your work. It's really awesome to have Nuxt 4 and Storybook 10 support, so this is much appreciated.
I have a few comments of mostly very minor nature.
The biggest question mark in my head is about the switch from ubuild to tsdown. This is fine with me in principle, but then we should probably migrate also the nuxt module to it - and not use two different builders. There is also the 'official' successor obuild. @chakAs3 do you have an opinion here?
examples/showcase/package.json
Outdated
| "@storybook/addon-docs": "9.1.16", | ||
| "@storybook/addon-links": "9.1.16", | ||
| "storybook": "9.1.16" | ||
| "@nuxtjs/storybook": "workspace:*", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think using workspace here would break the examples in stackblitz, eg https://storybook.nuxtjs.org/examples/basic. Do you happen to know how stackblitz handles workspace dependencies?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question, I will look into that. What are your thoughts on changing this to:
"@nuxtjs/storybook: latest",
That would keep the StackBlitz examples up to date w/o a maintenance burden.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These examples will fail in CI due to the changes. We can update the versions back to "@nuxtjs/storybook": "latest" once the packages are bumped and released.
|
Thanks @akornmeier for the contribution. I already have an open PR (#980) for the Nuxt 4 + Storybook 10 update, with the Windows e2e tests being the only blocker there. The unbuild → tsdown migration is a separate concern, and it’s better to handle it in its own PR with a clear justification of the switch. @tobiasdiez I’m not sure we should move to a new bundler right now or just stay aligned with the Nuxt ecosystem and keep unbuild. We can always do a proper migration later if it turns out necessary. |
- Upgrade all Storybook packages from 10.0.8 to 10.1.0 - Switch storybook-addon build system from tsdown to unbuild - Revert starter example configs to TypeScript with proper types - Simplify example configs by removing viteFinal workarounds - Add resolveModule helper for ESM/CJS compatibility - Add useRouter composable override for Storybook context - Pre-bundle React dependencies in Vite config for addon-docs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This pull request upgrades the Nuxt Storybook module to support Storybook 10 (ESM-only) and Nuxt 4, introducing breaking changes that require Node.js 20.19+ and updates to dependency management, build configuration, and examples.
Key Changes:
- Upgrades all Storybook dependencies from 9.x to 10.x and updates peerDependencies to reflect minimum supported versions
- Adds
tsdownconfiguration for improved ESM build output and introduces Vite pre-bundling workarounds to prevent race conditions - Updates all example projects (playground, starter, showcase, tailwind) and documentation to reflect new requirements and configuration patterns
Reviewed changes
Copilot reviewed 21 out of 22 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| playground/package.json | Updates dependencies to Nuxt 4.2.1, Storybook 10.1.0, and adds eslint-plugin-storybook for improved linting |
| packages/storybook-addon/tsdown.config.ts | Adds new build configuration using tsdown for ESM-compliant output with separate browser and node entry points |
| packages/storybook-addon/tsconfig.json | Updates TypeScript config to include tsdown.config.ts and DOM libraries for browser compatibility |
| packages/storybook-addon/src/preview.ts | Adds re-exports from @storybook/vue3/entry-preview to support Storybook 10's ESM architecture |
| packages/storybook-addon/src/preset.ts | Adds resolveModule helper, disables app manifest feature, pre-bundles React dependencies, and updates core preset paths |
| packages/storybook-addon/preset.js | Changes export from preset.mjs to preset.cjs (potential issue identified) |
| packages/storybook-addon/package.json | Updates Storybook dependencies to 10.1.0, adds preset import export, updates Node engine to 20.19.0, and adds tsdown |
| packages/nuxt-module/package.json | Updates chalk, storybook devDependency, and vite versions for Storybook 10 compatibility |
| package.json | Upgrades ESLint config, test utils, and adds eslint-plugin-storybook to root dependencies |
| examples/tailwind/package.json | Updates Storybook to 10.1.0 but keeps Nuxt at 3.20.1 (inconsistency with other examples) |
| examples/tailwind/nuxt.config.ts | Removes empty line for cleaner formatting |
| examples/tailwind/.storybook/main.js | Reorders configuration to put framework first, consistent with Storybook conventions |
| examples/starter/package.json | Updates to Nuxt 4.2.1 and Storybook 10.1.0 with workspace references |
| examples/showcase/package.json | Updates package name, upgrades dependencies to Nuxt 4.2.1 and Storybook 10.1.0 |
| examples/showcase/nuxt.config.ts | Refactors runtimeConfig to use public namespace for client-accessible values |
| examples/showcase/.storybook/main.js | Reorders configuration to put framework first |
| eslint.config.mjs | Integrates eslint-plugin-storybook with recommended flat config settings |
| docs/package.json | Updates Nuxt to 4.2.1 for documentation site |
| README.md | Adds Vite optimization configuration guidance and updates requirements to reflect Nuxt 3.18.1+/4+ and Storybook 10+ support |
| CHANGELOG.md | Documents breaking changes, enhancements, fixes, and migration guide for Storybook 10 and Nuxt 4 upgrade |
| .github/workflows/e2e.yml | Updates STORYBOOK_VERSION environment variable to 10.1.0 for CI testing |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
CHANGELOG.md
Outdated
|
|
||
| ### 🚨 Breaking Changes | ||
|
|
||
| - ⚠️ **Requires Nuxt 4.0.0+** - Dropped support for Nuxt 3.x |
Copilot
AI
Nov 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changelog states "Requires Nuxt 4.0.0+" and "Dropped support for Nuxt 3.x", but the peerDependencies in package.json still allow "^3.18.1 || ^4.0.0". This is inconsistent. Either the peerDependencies should be updated to only require Nuxt 4, or this breaking change description should be corrected to reflect continued support for Nuxt 3.18.1+.
| - ⚠️ **Requires Nuxt 4.0.0+** - Dropped support for Nuxt 3.x | |
| - ⚠️ **Requires Nuxt 3.18.1+ or 4.0.0+** - Supports Nuxt 3.18.1 and Nuxt 4.0.0 or later |
version is released.
| "pnpm": { | ||
| "overrides": { | ||
| "@nuxtjs/storybook": "workspace:*" | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adds support for local testing of the local packages, while keeping the package explicitly set to @nuxtjs/storybook@latest in the StackBlitz examples/* directories.
- Switch CI from PowerShell to bash for cross-platform consistency - Use `echo | CI=true npx nuxi init` to handle interactive prompts - Replace `storybook init` with manual Storybook config creation
|
@chakAs3 / @tobiasdiez - The PR is ready for review. I reverted the bundler change, made the edits Tobias suggested, and updated e2e.yml to pull local packages from Verdaccio. This allows the use of |
|
@akornmeier, thanks for the changes. I tested this PR locally and found a critical regression in the main Nuxt application. The Nuxt package update within this PR is causing our Storybook module to break the loading of build assets because it fails to resolve necessary virtual files. @tobiasdiez, we need to add some tests against the main Nuxt app to check it is running properly. |
@chakAs3 - Thanks for looking into this. I hadn't seen this behavior in the stories. How can I replicate this issue locally? I'll dive into the error and fix it. |
Thanks for flagging this @tobiasdiez! After investigation, this change from /iframe.html to / is actually expected and correct behavior — not a regression. What's Happening The CustomNav.vue component displays the current route path: <!-- examples/showcase/components/CustomNav.vue -->
<div class="text-center p-4 op-50">
Current route: <code>{{ route.path }}</code>
</div>And the "Router: Home" story explicitly navigates to /: // examples/showcase/components/CustomNav.stories.ts
export const Home: Story = {
render(args) {
return {
setup() {
useRouter().push('/') // ← Pushes to root route
return { args }
},
template: '<div><CustomNav /></div>',
}
},
}Why the Old Behavior Was Incorrect
The old behavior showed /iframe.html because the Nuxt router wasn't properly isolated — it was seeing the actual browser URL (Storybook renders stories in an iframe at /iframe.html). With this PR, the Documentation References
Summary This Chromatic diff shows the router integration is now working correctly. The visual change is expected and represents a fix rather than a regression. |
@chakAs3 - I think I found the culprit: Root Cause: Storybook was starting during Nuxt's module setup() phase, before Nuxt's HTTP server was listening. When Storybook's proxy tried to connect to localhost:3000, it failed with EAGAIN errors. Fix: Defer Storybook startup to the listen hook: // packages/nuxt-module/src/module.ts
nuxt.hook('listen', () => {
setupStorybook(options, nuxt)
})I also added an integration test to help detect this behavior and prevent regressions in the future. |
Moves Storybook initialization from module setup to the 'listen' hook, ensuring Nuxt's HTTP server is ready before Storybook's proxy attempts to connect. This fixes EAGAIN proxy errors for /_nuxt/* requests. - Resolves virtual file resolution errors reported in nuxt-modules#981 - Storybook proxy now reliably connects to Nuxt dev server




🚀 Nuxt 3.18.1+ and Nuxt 4+ / Storybook 10+ Support
This pull request introduces major upgrades and breaking changes to support Storybook 10 and Nuxt 4, along with significant improvements to developer experience and dependency management. The update transitions all relevant dependencies, configurations, and documentation to ensure compatibility with the latest ESM-only architecture of Storybook 10 and the new requirements of Nuxt 4. It also adds workarounds for common issues with module pre-bundling, updates ESLint configuration, and refines package build and export settings.
Closes: #963
Key changes include:
Major Breaking Changes and Upgrades
Storybook 10 and Nuxt 4 Support: Upgrades all dependencies and peer dependencies to require Storybook 10 (ESM-only) and Nuxt 4, dropping support for Nuxt 3.x and Storybook 9.x. Updates minimum Node.js version to 20.19+. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13]
Package and Build System Updates: Refactors the
storybook-addonpackage to usetsdownfor building, updates exports for ESM compatibility, and revises bundler entry points for better alignment with Storybook 10's architecture. [1] [2] [3] [4]Dependency and Configuration Enhancements
Vite Pre-bundling Workarounds: Adds
viteFinalconfiguration in example.storybook/main.jsfiles and documents how to pre-bundle critical dependencies to avoid race conditions and module resolution errors during Storybook startup. [1] [2] [3] [4]Example and Playground Updates: Updates all example projects (
showcase,starter,tailwind) to use the new Storybook 10 and Nuxt 4 versions, and applies the new Vite and Storybook configuration patterns. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]Developer Experience and Linting
eslint-plugin-storybookwith recommended settings for improved linting of Storybook files. [1] [2] [3]Documentation and Migration
These changes ensure the project is fully compatible with the latest releases of Nuxt and Storybook, improve reliability during development, and provide clear guidance for users upgrading from previous versions.