or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

index.mddocs/

@emotion/sheet

@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.

Package Information

  • Package Name: @emotion/sheet
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @emotion/sheet

Core Imports

import { StyleSheet, type Options } from "@emotion/sheet";

For CommonJS:

const { StyleSheet } = require("@emotion/sheet");

Basic Usage

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();

Architecture

@emotion/sheet is built around a single StyleSheet class that manages multiple <style> elements for optimal performance:

  • Performance Optimization: Uses up to 65,000 rules per style tag in speedy mode
  • Development Mode: Text node insertion for DevTools editing capabilities
  • Production Mode: Fast insertRule() API for maximum performance
  • Flexible Insertion: Support for custom containers, insertion points, and positioning
  • CSP Compliance: Nonce attribute support for Content Security Policy
  • SSR Support: Hydration capabilities for server-side rendered styles

Capabilities

StyleSheet Class

Main 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;
}

Rule Insertion

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; }
  }
`);

Stylesheet Management

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 */");

Server-Side Rendering Support

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);

Configuration Options

Container Configuration

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
});

Performance Configuration

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
});

Security Configuration

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">

Insertion Control

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
});

Error Handling

@emotion/sheet includes built-in error handling and validation:

Rule Validation

  • @import Order Validation: Warns when @import rules are inserted after other rules
  • Invalid Rule Handling: Catches and reports malformed CSS rules in speedy mode
  • Development Warnings: Provides detailed error messages in development mode

Common Error Patterns

// 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

Performance Characteristics

  • Speedy Mode: Up to 65,000 CSS rules per <style> element
  • Development Mode: One rule per <style> element for source map support
  • Auto-scaling: Automatically creates new <style> elements as needed
  • Memory Efficient: Minimal overhead for rule tracking and management
  • Cross-browser: Handles Firefox-specific style sheet access patterns