Skip to content

Client SDK: React Version Compat Error in Goose #90

@aharvard

Description

@aharvard

React 19 compatibility

Summary

When using @mcp-ui/client in Goose (React 19 with Electron + Vite), we hit a runtime error about a mismatched React element/runtime. This usually happens when a dependency ships its own copy of React or react/jsx-runtime, or when multiple React versions end up installed. One way to make mcp-ui work smoothly across apps is to treat React as a peerDependency and keep it external to the bundle (including react/jsx-runtime), so the host app provides a single consistent React.

Error

A React Element from an older version of React was rendered. This is not supported. It can happen if:
- Multiple copies of the "react" package is used.
- A library pre-bundled an old copy of "react" or "react/jsx-runtime".
- A compiler tries to "inline" JSX instead of using the runtime.

Context

  • Host: Electron + Vite
  • React: 19.x in the host
  • Affected package: @mcp-ui/client (and potentially other @mcp-ui/* packages)
  • We already alias/dedupe react and react-dom in Vite; the issue surfaced because react/jsx-runtime was not also aliased/externalized.

Our host workaround (Vite) to force a single React runtime everywhere:

// vite.renderer.config.mts
resolve: {
  alias: {
    react: resolve(__dirname, 'node_modules/react'),
    'react-dom': resolve(__dirname, 'node_modules/react-dom'),
    'react/jsx-runtime': resolve(__dirname, 'node_modules/react/jsx-runtime.js'),
    'react/jsx-dev-runtime': resolve(__dirname, 'node_modules/react/jsx-dev-runtime.js'),
  },
  dedupe: ['react', 'react-dom'],
}

Reference (host config): https://github.com/block/goose/blob/2e2369f8b61f60aad2c04b739e1a2fdc6547d266/ui/desktop/vite.renderer.config.mts

Possible solutions

  1. Make React peer dependencies (not dependencies)

    • In each published package:
      • peerDependencies:
        • "react": "^18 || ^19"
        • "react-dom": "^18 || ^19"
      • Keep react/react-dom in devDependencies for local dev/test, but not in dependencies.
  2. Externalize React and the JSX runtime in the build

    • Ensure the bundler does not include React or JSX runtime in published artifacts:
      • external: ['react', 'react-dom', 'react/jsx-runtime', 'react/jsx-dev-runtime']
  3. Validate against React 18 and 19

    • Add a CI matrix or test locally against both versions.
    • Update types/TS config as needed for React 19 (e.g., @types/react, @types/react-dom if used).

Outcome

  • Consumers control the React version (standard practice).
  • Avoids duplicate/mismatched React instances and the runtime error above.
  • Reduces need for brittle alias workarounds in host apps.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions