When you have multiple packages in a pnpm monorepo that all use MUI, you can end up with duplicate MUI instances. This causes bundle bloat and can lead to subtle bugs. Here's how to use pnpm's public-hoist-pattern to share a single MUI instance across all packages.
In a monorepo with multiple apps, each package might declare its own MUI dependencies:
apps/
admin/
package.json # @mui/material: ^7.0.0
worker/
package.json # @mui/material: ^7.0.0
packages/
ui/
package.json # @mui/material: ^7.0.0
This leads to:
Use pnpm's public-hoist-pattern to hoist MUI packages to the root, making a single instance available to all packages.
Create or update .npmrc at the monorepo root:
public-hoist-pattern[]=@mui/*
This tells pnpm to hoist all @mui/* packages to the root node_modules, making them accessible to all workspace packages.
Declare MUI dependencies only in the root package.json:
{
"dependencies": {
"@mui/icons-material": "^7.3.6",
"@mui/lab": "7.0.1-beta.20",
"@mui/material": "^7.3.6",
"@mui/material-nextjs": "^7.3.6",
"@mui/x-data-grid-pro": "^8.23.0",
"@mui/x-date-pickers": "^8.23.0"
}
}
Import MUI as normal. The imports resolve to the hoisted instance:
// packages/ui/src/components/Button.tsx
import Button from '@mui/material/Button';
import IconButton from '@mui/material/IconButton';
import ContentCopy from '@mui/icons-material/ContentCopy';
You can hoist other shared packages too:
public-hoist-pattern[]=@mui/*
public-hoist-pattern[]=@toolpad/*
public-hoist-pattern[]=@emotion/*