Skip to main content
useInsertionEffect is a version of useEffect that fires before any DOM mutations.
useInsertionEffect is for CSS-in-JS library authors. Unless you’re working on a CSS-in-JS library and need a place to inject styles, you probably want useEffect or useLayoutEffect instead.

Parameters

() => (() => void) | void
required
The function with your Effect’s logic. Your effect function can optionally return a cleanup function.
  • React will call your effect function before any DOM mutations
  • React will call your cleanup function before the component is removed
  • If dependencies change, React will run cleanup, then run your effect with new values
Array<mixed> | void | null
The list of all reactive values referenced inside the effect code. Works the same as useEffect dependencies.
  • If omitted, the effect runs after every render
  • If [] (empty array), the effect runs only once (on mount)
  • If [dep1, dep2], the effect runs when any dependency changes

Returns

useInsertionEffect returns undefined.

Usage

Injecting dynamic styles from CSS-in-JS libraries

Traditionally, you would style React components using plain CSS:
Some teams prefer to author styles directly in JavaScript code instead of writing CSS files. This usually requires using a CSS-in-JS library or tool. There are three common approaches:
  1. Static extraction to CSS files with a compiler
  2. Inline styles: <div style={{ ... }}>
  3. Runtime injection of <style> tags
If you use CSS-in-JS with runtime injection, use useInsertionEffect:
useInsertionEffect is better than injecting styles during render or in useLayoutEffect because it ensures that by the time other Effects run in your components, the <style> tags have already been injected.

How CSS-in-JS libraries use this

Basic style injection

CSS-in-JS with dynamic values

Styled components pattern

Effect Timing Comparison

Timing: Render → useInsertionEffect → DOM mutations → Layout effects → PaintUse for: Injecting <style> tags for CSS-in-JS

TypeScript

Troubleshooting

Why not just use useEffect or useLayoutEffect?

Can I read DOM in useInsertionEffect?

No, you cannot read from the DOM in useInsertionEffect because the DOM hasn’t been updated yet:

I’m not building a CSS-in-JS library - do I need this?

No! Unless you’re authoring a CSS-in-JS library, you should use:
  • useEffect for most side effects
  • useLayoutEffect for measuring DOM or synchronous mutations
  • Plain CSS or CSS modules for styling

Best Practices

Only for CSS-in-JS libraries

useInsertionEffect is a specialized hook for library authors:

Prevent duplicate injections

Clean up injected styles

When to use useInsertionEffect

Use useInsertionEffect when:
  • ✅ Building a CSS-in-JS library
  • ✅ Injecting <style> tags dynamically
  • ✅ Need to inject styles before layout is calculated
Use useLayoutEffect when:
  • ✅ Measuring DOM elements
  • ✅ Reading layout (getBoundingClientRect, offsetHeight, etc.)
  • ✅ Synchronous DOM mutations before paint
Use useEffect when:
  • ✅ Everything else!
  • ✅ Data fetching
  • ✅ Setting up subscriptions
  • ✅ Logging and analytics
  • ✅ Most side effects

Real-World Example

Here’s how a CSS-in-JS library might implement a complete solution: