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

@leafygreen-ui/emotion

v5.2.0

Published

leafyGreen UI Kit's Custom Instance of Emotion

Downloads

397,089

Readme

Emotion

npm (scoped)

Installation

PNPM

pnpm add @leafygreen-ui/emotion

Yarn

yarn add @leafygreen-ui/emotion

NPM

npm install @leafygreen-ui/emotion

LeafyGreen Internal Emotion Instance

This package should be used only in LeafyGreen components (i.e. @leafygreen-ui/* packages).

For external applications, prefer using @emotion/react (or similar), or an app-specific custom instance of Emotion.

Why? If any @leafygreen-ui/* dependencies are not up to date, this could cause multiple copies of @leafygreen-ui/emotion to be installed, resulting in unpredictable styling.

Server-side Rendering

Because we use a custom instance of Emotion to allow for styles defined in LeafyGreen to be easily overwritten, there's an additional step that must be taken to use our components when performing server-side rendering.

We expose three methods as named exports that are also exposed by the base emotion-server package: renderStylesToString, renderStylesToNodeStream, and extractCritical. You can find documentation on usage of each of the methods in the official Emotion documentation.

NOTE: If you are already server-side rendering an application using Emotion, you will use the methods exposed in @leafygreen-ui/emotion instead of, NOT in addition to the methods exposed by emotion-server.

Example

import { renderToString } from 'react-dom/server';
import { renderStylesToString } from '@leafygreen-ui/emotion';
import App from './App';

const html = renderStylesToString(renderToString(<App />));

SSR Compatibility

Emotion generates styles at runtime and injects them into the DOM. For server-side rendering, styles must be extracted during rendering and inserted into the HTML before it's sent to the client. Without proper configuration, you'll see a flash of unstyled content (FOUC).

⚠️ Important:

  • Emotion does not currently support React Server Components. You must use 'use client' directive in Next.js.
  • Ensure you're using the latest version of any emotion packages alongside this package.
  • LeafyGreen UI components may require additional configuration beyond what's documented here.

Framework Guides


Next.js (App Router)

1. Create the Emotion Registry

Create a new file at src/app/EmotionRegistry.tsx:

'use client';

import { useServerInsertedHTML } from 'next/navigation';
import { cache, CacheProvider } from '@leafygreen-ui/emotion';

export default function EmotionRegistry({
  children,
}: {
  children: React.ReactNode,
}) {
  useServerInsertedHTML(() => {
    const names = Object.keys(cache.inserted);
    if (names.length === 0) return null;

    let styles = '';
    for (const name of names) {
      const style = cache.inserted[name];
      if (typeof style === 'string') {
        styles += style;
      }
    }

    return (
      <style
        data-emotion={`${cache.key} ${names.join(' ')}`}
        dangerouslySetInnerHTML={{ __html: styles }}
      />
    );
  });

  return <CacheProvider value={cache}>{children}</CacheProvider>;
}

2. Add the Registry to Your Root Layout

Wrap your application in src/app/layout.tsx:

import type { Metadata } from 'next';
import EmotionRegistry from './EmotionRegistry';

export const metadata: Metadata = {
  title: 'My App',
  description: 'My application description',
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body>
        <EmotionRegistry>{children}</EmotionRegistry>
      </body>
    </html>
  );
}

3. Use in Client Components

The css function only works in Client Components:

'use client';

import { css } from '@leafygreen-ui/emotion';

export default function MyComponent() {
  return (
    <h1
      className={css`
        color: red;
      `}
    >
      Hello World
    </h1>
  );
}

Next.js (Pages Router)

Add Emotion's critical CSS extraction to your _document file:

import { extractCritical } from '@leafygreen-ui/emotion';

export default class AppDocument extends Document {
  static async getInitialProps(
    ctx: DocumentContext,
  ): Promise<DocumentInitialProps> {
    const initialProps = await Document.getInitialProps(ctx);
    const { css, ids } = extractCritical(initialProps.html || '');

    return {
      ...initialProps,
      styles: (
        <>
          {initialProps.styles}
          <style
            data-emotion={`css ${ids.join(' ')}`}
            dangerouslySetInnerHTML={{ __html: css }}
          />
        </>
      ),
    };
    // ...
  }
}

React Router v7+

This guide covers Framework mode for React Router.

1. Configure Server Entry

Update `entry.server.tsx`:

import { PassThrough } from 'node:stream';
import type { EntryContext } from 'react-router';
import { createReadableStreamFromReadable } from '@react-router/node';
import { ServerRouter } from 'react-router';
import { renderToPipeableStream } from 'react-dom/server';
import { cache, extractCritical, CacheProvider } from '@leafygreen-ui/emotion';

const ABORT_DELAY = 5_000;

export default function handleRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
routerContext: EntryContext,
) {
  return new Promise<Response>((resolve, reject) => {
  let statusCode = responseStatusCode;
  const chunks: Buffer[] = [];

      const { pipe, abort } = renderToPipeableStream(
        <CacheProvider value={cache}>
          <ServerRouter context={routerContext} url={request.url} />
        </CacheProvider>,
      );

      const collectStream = new PassThrough();
      collectStream.on('data', chunk => chunks.push(chunk));

      collectStream.on('end', () => {
        const html = Buffer.concat(chunks).toString('utf-8');
        const { css, ids } = extractCritical(html);
        const emotionStyleTag = `<style data-emotion="css ${ids.join(' ')}">${css}</style>`;
        const htmlWithStyles = html.replace('</head>', `${emotionStyleTag}</head>`);

        const body = new PassThrough();
        const stream = createReadableStreamFromReadable(body);

        responseHeaders.set('Content-Type', 'text/html');
        resolve(
          new Response(stream, {
            headers: responseHeaders,
            status: statusCode,
          }),
        );

        body.write(htmlWithStyles);
        body.end();
      });

      collectStream.on('error', reject);
      pipe(collectStream);
      setTimeout(abort, ABORT_DELAY);

  });
}

2. Configure Client Entry

Update entry.client.tsx:

import { startTransition, StrictMode } from 'react';
import { hydrateRoot } from 'react-dom/client';
import { HydratedRouter } from 'react-router/dom';
import { CacheProvider, cache } from '@leafygreen-ui/emotion';

startTransition(() => {
  hydrateRoot(
    document,
    <StrictMode>
      <CacheProvider value={cache}>
        <HydratedRouter />
      </CacheProvider>
    </StrictMode>,
  );
});

Gatsby.js

⚠️ Not Currently Supported

There is a peer dependency mismatch between @leafygreen-ui/emotion and gatsby-plugin-emotion. As a result, we do not currently support GatsbyJS projects out of the box. If you need Emotion in a Gatsby project, refer to the Gatsby Emotion documentation.