Waku in a Monorepo Setup

Avoid duplicate React installs and common workspace issues.


Avoid Duplicate React Installs

The most common Waku monorepo problem is loading more than one copy of React. It can happen when a workspace package installs its own react dependency instead of using the app's copy.

Typical symptoms include errors like:

TypeError: Cannot read properties of null (reading 'use')

or React hook errors that only happen when importing a component from another workspace package.

For local workspace packages, prefer declaring React packages as peer dependencies. For example, a shared UI package can keep React available for local development without bundling its own runtime copy:

{
  "peerDependencies": {
    "react": "latest",
    "react-dom": "latest"
  },
  "devDependencies": {
    "react": "latest",
    "react-dom": "latest"
  }
}

The Waku app should keep the actual runtime dependencies:

{
  "dependencies": {
    "react": "latest",
    "react-dom": "latest",
    "react-server-dom-webpack": "latest",
    "waku": "latest"
  }
}

Dedupe React in Vite

If your package manager still resolves multiple React copies, configure Vite through waku.config.ts:

import { defineConfig } from 'waku/config';

export default defineConfig({
  vite: {
    resolve: {
      dedupe: ['react', 'react-dom'],
    },
  },
});

This asks Vite to resolve react and react-dom from a single location when bundling linked workspace packages.

Waku depends on React, React DOM, and React Server DOM Webpack versions that are meant to work together. In a workspace, keep those versions aligned across apps and packages before debugging Waku-specific behavior.

Shared Packages

Shared packages imported by a Waku app should publish or expose code that Vite can process. For TypeScript or JSX source packages, make sure the package's exports point to files your app can import, and avoid importing server-only modules from client components.

If a shared package has a file that uses React client APIs such as useState or useEffect, that file still needs a 'use client' directive when it can be imported from a server component.

See issue #676 for the original duplicate React report.

designed bycandycode alternative graphic design web development agency San Diego