A runtime CSS-in-JS library builds a stylesheet while React 7,897 renders, by injecting rules into the document. A Server Component renders on the server, once, with no document to inject into and no client bundle to carry the library. So every runtime library in the App Router is confined to Client Components and needs a registry that collects the rules from the server pass and flushes them into the streamed HTML ahead of the markup that uses them: a registry object, the useServerInsertedHTML hook, and a Client Component wrapping the tree.
"use client"; // useState from react, useServerInsertedHTML from next/navigation,
// ServerStyleSheet and StyleSheetManager from styled-components
export default function Registry({ children }: { children: React.ReactNode }) {
const [sheet] = useState(() => new ServerStyleSheet());
useServerInsertedHTML(() => {
const styles = sheet.getStyleElement();
sheet.instance.clearTag();
return <>{styles}</>;
});
if (typeof window !== "undefined") return <>{children}</>;
return <StyleSheetManager sheet={sheet.instance}>{children}</StyleSheetManager>;
}Wrap children in the root layout with it and set compiler: { styledComponents: true } in next.config.ts. styled-jsx, which ships inside Next.js 10,514 already, follows the same shape with createStyleRegistry.
| Library | Styles generated | Server Components | Notes |
|---|---|---|---|
| styled-components 6.5.3 247,596 | at render | Client only | registry plus SWC 553,439 flag |
| vanilla-extract 1.21.2 | at build | yes | typed .css.ts files |
| PandaCSS, StyleX | at build | yes | emit utility classes |
| Emotion 643,768 | at render | not yet | support still in progress |
Anything resolved at build time produces a plain stylesheet, so it needs no registry, no client boundary and no runtime kilobytes. vanilla-extract (vanilla-extract.style (https://vanilla-extract.style), MIT) is the closest thing to typed CSS Modules: you write style({ padding: 16 }) in a .css.ts file, the build evaluates it and emits a class name, and TypeScript checks the token names.