npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

server-mui

v0.1.0

Published

Dynamic Material UI for React Server Components

Readme

npm

License: MIT

Why Use This?

The official recommendation for using Mui with React Server Components is to use Pigment CSS, however it comes with large compromises and changes to your codebase. This library aims to provide a drop-in replacement for Mui in Server Components.

🔹 Fix Pigment CSS Limitations

// Pigment CSS fails here - this works!
<Box sx={ await fetchSx() } />
  • Pigment requires the keys in the sx prop to be statically defined at build time, but React Server Components might run on each request

🔹 Keep MUI Functionality

// Same props you already use (even with breakpoints)
<Grid container spacing={{ xs: 2, md: 4 }} />

🔹 Pre-render to html

// This syntax in a Server Component
<Box sx={{ px: 2 }} />

// Will get pre-rendered to the following using Mui's theme spacing
<div style="padding-left:16px; padding-right:16px" />

🔹 CSS Variables are optional

// Conditionals can be used without CSS variables
<Container sx={theme.palette.mode === "dark" ? darkStyle : lightStyle} />

🔹 Automatic Server/Client Split

// Works in both environments (Server Components ignore dynamic props like onClick)
<Box onClick={log} sx={dynamicStyles} />

Installation

npm install server-mui @mui/material

Quick Migration

  1. Import the Theme Provider
import { ThemeProvider } from 'server-mui';
  1. Wrap Root Layout
// app/layout.tsx
<body>
  <ThemeProvider theme={yourTheme}>
    {children}
  </ThemeProvider>
</body>
  1. Replace Layout Components
- import { Box } from '@mui/material';
- import Stack from "@mui/material/Stack
+ import { Box } from 'server-mui';
+ import Stack from 'server-mui/lib/Stack'
  • Note: Currently only Box, Stack, Grid, and Container are exported (similar to PigmentCSS). You can use the regular Mui Components for the others since they are mostly interactive (eg. Button and Accordion require client side API's). You can also fashion your own with the styled function below.
  1. Replace Styled Function
- import { styled } from '@mui/material/styles';
+ import { styled } from 'server-mui/lib/styles';

Note

The api is similar to Mui and falls back to Mui in client contexts, so you can either replace your mui components or import components exclusively on the server and use them.

// Either of these work

// Either import and replace all your Mui references
import { Box, ThemeProvider } from 'server-mui';

// Or import it separately and use only in your Server Components
import { Box as ServerBox, ThemeProvider as ServerThemeProvider } from 'server-mui';

See below for a more advanced way to incorporate with Mui


Key Features

Dynamic Server Styles

// Server Component
<Box sx={{
  bgcolor: (await getUserPreferences()).color,
  p: { xs: 2, md: 4 }
}} />

Client Interoperability

'use client';
import { Box } from 'server-mui';

// Works with client hooks
<Box sx={{ color: isHovered ? 'red' : 'blue' }} />

Full Theme Access

// Type-safe theme values
<Box sx={theme => ({
  border: `1px solid ${theme.palette.divider}`,
  [theme.breakpoints.up('md')]: { p: 4 }
})} />

When to Use

| | Pigment CSS | This Lib | |-------------------------|-------------|----------| | Build-Time Styles | ✅ Best | ✅ Works | | Runtime Values | ❌ Broken | ✅ Fixed | | RSC Compatibility | ⚠️ Partial | ✅ Full | | Bundle Size | 15kb | 2kb core |


Full Example

The following entire page will be pre-rendered server side into regular HTML in NextJS. Other React Server frameworks are supported as well.

// app/page.tsx
import { Stack, Box, styled, useTheme } from 'server-mui';

const DynamicCard = styled('div')(({ theme }) => ({
  padding: theme.spacing(2),
  transition: 'all 0.2s',
}));

export default async function Page() {
  const data = await fetchData();
  const spacing = useTheme().spacing

  return (
    <Stack spacing={4}>
      <DynamicCard sx={{
        bgcolor: data.color,
        '&:hover': { transform: 'scale(1.02)' }
      }}>
        {data.content}
      </DynamicCard>
      <Box sx={{ py: 4, m: spacing(4), color: "primary.main" }}> Example </Box>
    </Stack>
  );
}

// app/layout.tsx
import { ThemeProvider } from 'server-mui';

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  const theme = createTheme({});

  return (
      <html lang="en">
        <body>
          <ThemeProvider theme={theme}>{children}</ThemeProvider>
        </body>
      </html>
  );
}

ThemeProvider Options

The ThemeProvider accepts the following options to customize server-side behavior:

theme (Required)

  • Type: Theme (MUI theme object)
    The Material-UI theme to be used on the server.
    Example:
    import { createTheme } from '@mui/material/styles';
      
    const theme = createTheme({
      // Your theme configuration
    });

emotionKey (Optional)

  • Type: string
    Custom cache key for Emotion styles. Defaults to 'sui'.
    Use this to avoid class name collisions when multiple Emotion instances are present.

emotionInstance (Optional)

  • Type: Emotion
    Provide a custom Emotion instance. Useful when you want to share an existing Emotion instance.
    Defaults to the library's internal Emotion instance.

styleInjector (Optional)

  • Type:
    ({ headerStyles, uniqueClassName }: {
      headerStyles: string;
      uniqueClassName: string
    }) => React.ReactNode
    Custom component for adding generated styles to the html head.

Example Usage

import { ThemeProvider } from 'server-mui';

const RootLayout = ({ children }) => (
  <ThemeProvider
    theme={customTheme}
    emotionKey="my-app"
    emotionInstance={myEmotion}
    styleInjector={({ headerStyles, uniqueClassName }) => (
      <CustomStyleTag
        data-css={`${uniqueClassName}-styles`}
        css={headerStyles}
      />
    )}
  >
    {children}
  </ThemeProvider>
);

Advanced

Mui Interoperability

You can also use the library directly instead of as a replacement for Mui. You would just have to let us know your theme with the registerTheme function.

// In a client file like client.tsx
"use client";
import { Box } from "@mui/material";

// And in a server file app/page.tsx
import { Box as ServerBox } from "server-mui";

// And skip our ThemeProvider completely
import { registerTheme } from "server-mui";

export const RootLayout = async ({children}) => {
  registerTheme(theme)
  return <body>{children}</body>
}

// Or even process the sxProp yourself
import { processSx } from "server-mui"

export const MyButton = () => {
  return <button style={ processSx({ pt: 5 }).styleObject }> A button </button>
}

Note: we internally use Mui's unstable_styleFunctionSx to process the sxProp with the registered theme.


License
MIT