Skip to content

Conversation

@JReinhold
Copy link
Contributor

@JReinhold JReinhold commented Oct 23, 2025

Closes #

What I did

Added a new preset property, experimental_devServer, that is very similar in nature to experimental_serverChannel, in that it allows any addon/etc. to get access to the dev server instance. This is useful for attaching middlewares and other stuff to the dev server.

We want this so that @storybook/addon-mcp can attach a handler on the /mcp route without using the current Vite-based workaround.

With this, addons should be able to do:

// preset.js

export async function experimental_devServer(app){
  app.use('/my-custom-route', (req, res, next) => {
    ...
    next();
  });
  return app;
}

Checklist for Contributors

Testing

The changes in this PR are covered in the following automated tests:

  • stories
  • unit tests
  • integration tests
  • end-to-end tests

Manual testing

This section is mandatory for all contributions. If you believe no manual test is necessary, please state so explicitly. Thanks!

Documentation

  • Add or update documentation reflecting your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

Checklist for Maintainers

  • When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli-storybook/src/sandbox-templates.ts

  • Make sure this PR contains one of the labels below:

    Available labels
    • bug: Internal changes that fixes incorrect behavior.
    • maintenance: User-facing maintenance tasks.
    • dependencies: Upgrading (sometimes downgrading) dependencies.
    • build: Internal-facing build tooling & test updates. Will not show up in release changelog.
    • cleanup: Minor cleanup style change. Will not show up in release changelog.
    • documentation: Documentation only changes. Will not show up in release changelog.
    • feature request: Introducing a new feature.
    • BREAKING CHANGE: Changes that break compatibility in some way with current major version.
    • other: Changes that don't fit in the above categories.

🦋 Canary release

This pull request has been released as version 0.0.0-pr-32816-sha-28f59f53. Try it out in a new sandbox by running npx [email protected] sandbox or in an existing project with npx [email protected] upgrade.

More information
Published version 0.0.0-pr-32816-sha-28f59f53
Triggered by @JReinhold
Repository storybookjs/storybook
Branch jeppe/devserver-preset
Commit 28f59f53
Datetime Thu Oct 23 21:52:46 UTC 2025 (1761256366)
Workflow run 18763010372

To request a new release of this pull request, mention the @storybookjs/core team.

core team members can create a new canary release here or locally with gh workflow run --repo storybookjs/storybook publish.yml --field pr=32816

Summary by CodeRabbit

  • New Features

    • Added experimental component manifest generation system to extract and document component metadata, including code snippets, descriptions, and examples.
    • New /manifests/components.json endpoint for accessing generated component data.
    • Enhanced component introspection with React DocGen integration and JSDoc parsing.
  • Accessibility

    • Added aria-selected attribute to tab buttons for improved screen reader support.
  • Dependencies

    • Added react-docgen and comment-parser packages for enhanced component documentation analysis.

Summary by CodeRabbit

  • New Features
    • Experimental dev server preset system now enables addons and frameworks to extend the dev server with custom middleware
    • New experimental_devServer configuration option introduced for advanced server customization

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 23, 2025

📝 Walkthrough

Walkthrough

This pull request adds experimental dev server customization support. The dev server now applies an experimental_devServer preset after middleware initialization, enabling addons and frameworks to extend the dev server. The ServerApp interface is exported and receives an additional overload for simplified middleware registration.

Changes

Cohort / File(s) Summary
Dev server initialization
code/core/src/core-server/dev-server.ts
Added application of experimental_devServer preset after middleware initialization to allow extensibility via addons and frameworks.
Type exports and interfaces
code/core/src/types/modules/core-common.ts
Exported ServerApp interface (previously internal). Added new method overload use(...handlers: Middleware<T>[]): this; to support middleware without patterns. Added experimental_devServer?: ServerApp; configuration field to StorybookConfigRaw.

Sequence Diagram

sequenceDiagram
    participant Dev as Dev Server Init
    participant Middleware as Middleware<br/>Layer
    participant Preset as experimental_devServer<br/>Preset
    
    Dev->>Middleware: Apply standard middlewares
    Middleware-->>Dev: Middleware stack ready
    
    rect rgb(200, 220, 240)
    Note over Dev,Preset: New: Apply experimental preset
    Dev->>Preset: Apply experimental_devServer<br/>preset (if configured)
    Preset->>Preset: Register custom middlewares<br/>& hooks via ServerApp
    Preset-->>Dev: Extension complete
    end
    
    Dev-->>Dev: Dev server initialization<br/>complete
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

The changes are focused and straightforward: runtime preset application and targeted type/interface exports. However, care should be taken with the public API exports and ensuring the preset application doesn't disrupt existing initialization flow.

✨ Finishing touches
  • 📝 Docstrings were successfully generated.
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch jeppe/devserver-preset

Comment @coderabbitai help to get the list of available commands and usage tips.

@JReinhold JReinhold self-assigned this Oct 23, 2025
@JReinhold JReinhold changed the base branch from next to 10.1-with-canary-release October 23, 2025 21:51
@nx-cloud
Copy link

nx-cloud bot commented Oct 23, 2025

View your CI Pipeline Execution ↗ for commit e0eeba2

Command Status Duration Result
nx run-many -t build --parallel=3 ✅ Succeeded 48s View ↗

☁️ Nx Cloud last updated this comment at 2025-10-24 16:43:43 UTC

@storybook-app-bot
Copy link

storybook-app-bot bot commented Oct 23, 2025

Package Benchmarks

Commit: e0eeba2, ran on 24 October 2025 at 16:39:24 UTC

No significant changes detected, all good. 👏

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
code/core/src/types/modules/core-common.ts (1)

501-502: Add JSDoc documentation for the experimental field.

Consider adding JSDoc comments to document the purpose, usage, and example for this experimental feature. This is especially important for experimental APIs to help early adopters understand how to use them correctly.

Example documentation:

+  /**
+   * Extend the Storybook dev server with custom middleware and handlers.
+   * 
+   * This allows addons and frameworks to attach routes and middleware to the dev server instance.
+   * 
+   * @example
+   * ```ts
+   * experimental_devServer: async (app) => {
+   *   app.use('/my-custom-route', (req, res) => {
+   *     res.end('Custom response');
+   *   });
+   *   return app;
+   * }
+   * ```
+   */
  experimental_devServer?: ServerApp;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6867ca5 and e0eeba2.

📒 Files selected for processing (2)
  • code/core/src/core-server/dev-server.ts (1 hunks)
  • code/core/src/types/modules/core-common.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,jsx,json,html,ts,tsx,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{js,jsx,json,html,ts,tsx,mjs}: Run Prettier formatting on changed files before committing
Run ESLint on changed files and fix all errors/warnings before committing (use yarn lint:js:cmd <file>)

Files:

  • code/core/src/core-server/dev-server.ts
  • code/core/src/types/modules/core-common.ts
**/*.{ts,tsx,js,jsx,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Export functions from modules when they need to be unit-tested

Files:

  • code/core/src/core-server/dev-server.ts
  • code/core/src/types/modules/core-common.ts
code/**/*.{ts,tsx,js,jsx,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

In application code, use Storybook loggers instead of console.* (client code: storybook/internal/client-logger; server code: storybook/internal/node-logger)

Files:

  • code/core/src/core-server/dev-server.ts
  • code/core/src/types/modules/core-common.ts
{code/**,scripts/**}/**/*.{ts,tsx,js,jsx,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Do not use console.log, console.warn, or console.error directly unless in isolated files where importing loggers would significantly increase bundle size

Files:

  • code/core/src/core-server/dev-server.ts
  • code/core/src/types/modules/core-common.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: normal
  • GitHub Check: Core Unit Tests, windows-latest
🔇 Additional comments (3)
code/core/src/types/modules/core-common.ts (2)

228-228: LGTM: Exporting ServerApp is necessary for the public API.

Exporting the ServerApp interface allows addons and users to reference this type when implementing the experimental_devServer preset.


232-232: LGTM: New overload enables pattern-less middleware registration.

The additional overload for use(...handlers: Middleware<T>[]): this; correctly supports the Express/Polka pattern of registering middleware without a specific route pattern.

code/core/src/core-server/dev-server.ts (1)

54-55: LGTM: Preset application is correctly placed and implemented.

The experimental_devServer preset is applied at the right time—after core middleware initialization but before the server starts listening—allowing addons to extend the dev server with custom routes and middleware. The implementation correctly passes the app instance and follows the established preset pattern.

Comment on lines +501 to +502
experimental_devServer?: ServerApp;

Copy link
Contributor

@coderabbitai coderabbitai bot Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add corresponding entry in StorybookConfig interface for type completeness.

The experimental_devServer field is defined in StorybookConfigRaw but is missing from the StorybookConfig interface (lines 520-619). Following the pattern of other experimental fields like experimental_indexers (line 586), this should be added to StorybookConfig wrapped with PresetValue for proper type safety when users or addons define this in their configuration files.

Add this entry to the StorybookConfig interface (around line 587, after experimental_indexers):

  /** Process CSF files for the story index. */
  experimental_indexers?: PresetValue<StorybookConfigRaw['experimental_indexers']>;
  
+  /** Extend the dev server with custom middleware and handlers. */
+  experimental_devServer?: PresetValue<StorybookConfigRaw['experimental_devServer']>;

  /** Docs related features in index generation */
  docs?: PresetValue<StorybookConfigRaw['docs']>;

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In code/core/src/types/modules/core-common.ts around lines 501-502, the
experimental_devServer property exists on StorybookConfigRaw but is missing from
the StorybookConfig interface; add an entry to StorybookConfig (around line
~587, immediately after experimental_indexers) named experimental_devServer with
the same wrapping pattern as other experimental fields (i.e., use PresetValue
keyed to the ServerApp type or ServerApp | undefined) so the interface matches
StorybookConfigRaw and maintains type safety for user/addon configs.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shilman I don't want this to be exposed to users' config types, it's too early for that. experimental_indexers is different, because honestly that's not really experimental anymore.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 25, 2025

Warning

Docstrings generation - IN PROGRESS

Generating docstrings for this pull request

@JReinhold JReinhold merged commit e616765 into 10.1-with-canary-release Oct 26, 2025
56 checks passed
@JReinhold JReinhold deleted the jeppe/devserver-preset branch October 26, 2025 15:05
@yannbf yannbf added the patch:yes Bugfix & documentation PR that need to be picked to main branch label Oct 28, 2025
@ndelangen ndelangen removed the patch:yes Bugfix & documentation PR that need to be picked to main branch label Oct 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants