codingstairs
NotesEDULifeContact
⌕Search⌘K
koen

Navigation

  • Intro
  • Blog
  • Life

Get in touch

Send without signing in. Add your email if you'd like a reply.

  • Leave a message anonymously →
  • ✉ warragon112@gmail.com
  • KakaoTalk Open Chat ↗

© 2026 codingstairs

  • Notes
  • EDU
  • Search
  • Life
  • Contact
  • Legal
  • RSS
  • GitHub
Notes›frontend

React 19 and React Compiler

Published 2026-04-28· Updated 2026-05-18·0 views

React 19 and React Compiler

React 19 marks one of React's larger inflection points. Among its changes, React Compiler automates some of the memoization that used to be written by hand.

1. About React

React was created in 2011 by Jordan Walke at Facebook for an internal tool (News Feed) and was open-sourced at JSConf US in May 2013. The license is MIT (briefly BSD+Patents in 2017, then reverted to MIT).

Version When Event
0.14 2015 react-dom split out.
16 2017-09 Fiber rewrite. error boundary, fragments, portals.
16.8 2019-02 Hooks officially. useState, useEffect.
17 2020-10 "no new features" release. Gradual upgrade path.
18 2022-03 Concurrent renderer, automatic batching, useTransition.
19 2024-12 GA Server Components stable, use, Actions, ref-as-prop, <form action> integration.

Alongside 19 (as a separate package), React Compiler was released and has since reached its 1.0 stable release.

2. React 19 essentials

  • Actions — <form action={fn}> or useActionState and useFormStatus bundle the pending/error/optimistic state of form submission into a single API.
  • use(thenable) — unwrap promises or context directly inside a component. Pairs with Suspense.
  • ref as prop — forwardRef becomes effectively unnecessary. function X({ ref }) { ... } is now valid.
  • useOptimistic — a hook for optimistic UI updates.
  • Metadata integration — declare <title>, <meta>, <link rel="stylesheet"> anywhere in the component tree and React lifts them into the head.

3. Compiler-driven automation

In traditional React, re-render optimizations are written by hand.

const value = useMemo(() => heavy(a, b), [a, b])
const onClick = useCallback(() => setX(x + 1), [x])
const Memo = memo(Child)

Compiler analyzes component functions at build time and inserts memoization automatically so that the same input reuses the same result (the official docs call it "auto-memoization"). As a result, manual useMemo, useCallback, and memo calls become rarer. The output uses cache slots from react-compiler-runtime's c().

Preconditions apply. The code must follow React's rules.

  • Render functions are pure (same props/state yield the same output).
  • Do not mutate props or state during render.
  • Honor the rules of Hooks (top-level calls, no conditional calls).

When rules are broken, Compiler skips that component (opt-out). The eslint-plugin-react-compiler package catches violations ahead of time.

4. Where Compiler does not help

Auto memoization handles referential equality within component boundaries. The following still require human attention.

  • External mutation dependencies — patterns where useEffect deps include a changing object. Compiler does not wrap effect bodies.
  • Observer / subscription — IntersectionObserver and ResizeObserver callbacks need stable references for effect cleanup to work correctly. useCallback or useEffectEvent may be required.
  • AbortController patterns — calling abort on a controller created inside an effect must be done by hand in cleanup.
  • Spread deps — dynamic-length deps like useEffect(fn, [...deps]) cannot be guaranteed by Compiler.
  • External library callbacks — when a library requires the same reference (for example, matching addEventListener and removeEventListener pairs), explicit preservation is safer.

In short, Compiler reduces the need to "newly write manual memoization" but does not replace every case of it.

5. UI library comparison

Library First release Notes
React 2013 VDOM, Hooks, Server Components.
Vue 2014, Evan You reactive proxy, single-file components.
Svelte 2016, Rich Harris The compiler erases most of the runtime. Runes introduced in 5 (2024).
Solid 2021, Ryan Carniato fine-grained reactivity. Uses JSX.
Preact 2015 A small React-compatible implementation. About 3KB.
Qwik 2022, Misko Hevery resumability — a model that defers hydration.

Compiler is React's attempt to reduce the burden of manual memoization that is unique to React. Other libraries have different answers in the same place (Vue's reactive, Svelte's compile-time tracking, Solid's signals).

6. Install and setup

pnpm add react@19 react-dom@19
pnpm add -D babel-plugin-react-compiler eslint-plugin-react-compiler
// babel.config.js
export default {
  plugins: [
    ["babel-plugin-react-compiler", { /* options */ }]
  ]
}

Next.js wires it through the experimental.reactCompiler option in next.config.js, and Vite wires it via vite-plugin-react's babel.plugins entry.

7. Form actions in 19

import { useActionState } from "react"

async function submit(prev: State, form: FormData) {
  const r = await fetch("/api", { method: "POST", body: form })
  return await r.json()
}

export function NewItem() {
  const [state, action, pending] = useActionState(submit, { error: null })
  return (
    <form action={action}>
      <input name="title" />
      <button disabled={pending}>저장</button>
      {state.error && <p>{state.error}</p>}
    </form>
  )
}

8. The shape Compiler handles

// before: hand memoization
const items = useMemo(() => list.filter(p), [list, p])

// after: just an expression. Compiler stores it in a cache slot.
const items = list.filter(p)

9. Common pitfalls

Gradual adoption — Compiler can be enabled per file or per directory. In a large codebase, staged adoption is safer than enabling everything at once.

DevTools indication — components that Compiler applies to get a marker like "Memo ✨" in React DevTools. If it's missing, the component may have been skipped due to rule violations.

Strict Mode's double invocation — React 18+ Strict Mode intentionally runs effects twice. Code with side effects must be idempotent regardless of Compiler.

Auto-memoization is not free — the cache comparison itself adds cost. Reports indicate that very small components can actually become slower. The general recommendation is "enable Compiler, measure, then decide."

Coexistence with manual memoization — there is no need to forcibly remove existing useMemo and useCallback. Compiler does not stack its cache on top of them; it leaves them alone.

Closing thoughts

React Compiler significantly reduces the burden of manual memoization. It does not replace every case, though. Code that follows the rules + manual memoization preserved for exceptional cases (Observer, external callbacks, etc.) is the most balanced flow.

Next

  • nextjs-app-router
  • state-philosophy

We refer to the React official site, React Compiler docs, React 19 release notes, Rules of React, eslint-plugin-react-compiler, Vue.js, and SolidJS.

More in frontend

All in this category →
  • Dashboard widget uniformity — don''t leave 4 domains with 3 widgets
  • Admin UI — ResourceTable SSOT pattern
  • Page Loading UX
  • Native Integrations — OS Features
  • OCR · STT · TTS
  • SQLite — A Single-File DB for Local Apps