@emotion/sheet is a high-performance StyleSheet implementation for CSS-in-JS libraries. It efficiently manages dynamic style injection into the DOM using either fast insertRule() API for production or text node appending for development with DevTools support.
npm install @emotion/sheetimport { StyleSheet, type Options } from "@emotion/sheet";For CommonJS:
const { StyleSheet } = require("@emotion/sheet");import { StyleSheet } from "@emotion/sheet";
// Create a stylesheet with basic configuration
const sheet = new StyleSheet({
key: "my-styles",
container: document.head
});
// Insert CSS rules
sheet.insert("body { margin: 0; padding: 0; }");
sheet.insert(".button { background: #007bff; color: white; }");
// Clear all styles when needed
sheet.flush();@emotion/sheet is built around a single StyleSheet class that manages multiple <style> elements for optimal performance:
insertRule() API for maximum performanceMain class for managing high-performance stylesheets with configurable insertion strategies.
class StyleSheet {
constructor(options: Options);
// Public properties
isSpeedy: boolean;
ctr: number;
tags: HTMLStyleElement[];
container: Node;
key: string;
nonce: string | undefined;
prepend: boolean | undefined;
before: Element | null;
insertionPoint: HTMLElement | undefined;
// Public methods
insert(rule: string): void;
flush(): void;
hydrate(nodes: HTMLStyleElement[]): void;
}Constructor Options:
interface Options {
key: string;
container: Node;
nonce?: string;
speedy?: boolean;
prepend?: boolean;
insertionPoint?: HTMLElement;
}Insert CSS rules into the stylesheet with automatic performance optimization.
/**
* Insert a CSS rule into the stylesheet
* @param rule - CSS rule string (must be a single rule in speedy mode)
*/
insert(rule: string): void;Usage Examples:
import { StyleSheet } from "@emotion/sheet";
const sheet = new StyleSheet({
key: "app",
container: document.head
});
// Insert individual rules
sheet.insert("body { font-family: 'Helvetica Neue', sans-serif; }");
sheet.insert(".container { max-width: 1200px; margin: 0 auto; }");
// Insert media queries
sheet.insert("@media (max-width: 768px) { .container { padding: 20px; } }");
// Insert keyframes
sheet.insert(`
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
`);Clear all styles and reset the stylesheet state.
/**
* Remove all style elements from the document and reset internal state
*/
flush(): void;Usage Examples:
// Clear all styles when component unmounts or theme changes
sheet.flush();
// Reset and start fresh
sheet.insert("/* New styles after flush */");Adopt existing style elements for SSR hydration scenarios.
/**
* Move existing style elements into the sheet's management
* @param nodes - Array of style elements to adopt (typically from SSR)
*/
hydrate(nodes: HTMLStyleElement[]): void;Usage Examples:
// Hydrate SSR styles on client
const existingStyles = Array.from(
document.querySelectorAll('style[data-emotion="ssr"]')
);
const sheet = new StyleSheet({
key: "ssr",
container: document.head
});
sheet.hydrate(existingStyles);Specify where style elements should be inserted.
interface Options {
/** DOM node where style elements will be inserted (supports ShadowRoot) */
container: Node;
}Usage Examples:
// Standard head insertion
const sheet = new StyleSheet({
key: "app",
container: document.head
});
// Custom div container
const customContainer = document.createElement('div');
document.body.appendChild(customContainer);
const sheet = new StyleSheet({
key: "custom",
container: customContainer
});
// Shadow DOM support
const shadowHost = document.createElement('div');
const shadowRoot = shadowHost.attachShadow({ mode: 'open' });
const sheet = new StyleSheet({
key: "shadow",
container: shadowRoot
});Control performance optimization strategies.
interface Options {
/**
* Enable fast insertRule() mode for production performance
* Default: true in production, false in development
*/
speedy?: boolean;
}Usage Examples:
// Force speedy mode (production-like performance)
const fastSheet = new StyleSheet({
key: "fast",
container: document.head,
speedy: true
});
// Force development mode (DevTools editing support)
const devSheet = new StyleSheet({
key: "dev",
container: document.head,
speedy: false
});Content Security Policy compliance through nonce attributes.
interface Options {
/** CSP nonce value to set on style elements */
nonce?: string;
}Usage Examples:
// CSP nonce support
const sheet = new StyleSheet({
key: "secure",
container: document.head,
nonce: "random-nonce-value-from-server"
});
sheet.insert("body { background: white; }");
// Results in: <style data-emotion="secure" nonce="random-nonce-value-from-server">Fine-grained control over where styles are positioned in the DOM.
interface Options {
/**
* Identifier for data-emotion attribute
* Used to distinguish different stylesheet instances
*/
key: string;
/**
* @deprecated Use insertionPoint instead
* Insert styles at the beginning of container
*/
prepend?: boolean;
/**
* Specific DOM element to insert styles after
* Provides precise control over style positioning
*/
insertionPoint?: HTMLElement;
}Usage Examples:
// Basic key identification
const sheet = new StyleSheet({
key: "my-component",
container: document.head
});
// Precise insertion point control
const insertionMarker = document.createElement('meta');
insertionMarker.setAttribute('name', 'emotion-insertion-point');
document.head.appendChild(insertionMarker);
const sheet = new StyleSheet({
key: "positioned",
container: document.head,
insertionPoint: insertionMarker
});
// Deprecated prepend option (use insertionPoint instead)
const prependSheet = new StyleSheet({
key: "prepend",
container: document.head,
prepend: true
});@emotion/sheet includes built-in error handling and validation:
// This will trigger a warning in development
sheet.insert("body { color: red; }");
sheet.insert("@import url('fonts.css');"); // Warning: @import after other rules
// Invalid CSS will be caught in speedy mode
sheet.insert("invalid css {{{"); // Error reported in development<style> element<style> element for source map support<style> elements as needed