⚛️ React 19 New Features

Exploring some of the features of React 19.


React Compiler

React 19 introduces a new compiler, similar in spirit to those in Svelte and Vue. The React Compiler analyzes your components at build time, making React apps faster and automating tedious tasks that previously required manual optimization. This means less boilerplate, fewer bugs, and improved performance out of the box.

Automatic Memoization

Previously, developers had to use useMemo, useCallback, and memo to optimize re-renders and prevent unnecessary computations. Manual memoization can clutter code, is error-prone, and requires ongoing maintenance. With the new compiler, these hooks are no longer necessary—React will handle memoization automatically, reducing cognitive load and making codebases cleaner.

  • No more manual useMemo, useCallback, or memo in most cases.
  • The compiler analyzes dependencies and optimizes re-renders for you.
  • Legacy hooks still work for backward compatibility.

use() Hook

The use hook is a new primitive for reading and asynchronously loading resources such as promises or contexts. Unlike other hooks, use can be called inside loops and conditionals, making it more flexible and expressive.

  • use(context) replaces useContext(context).
  • use(promise) suspends until the promise resolves and returns its value.
  • Can be used for data fetching, context, or any resource that supports the "thenable" interface.

Example:

import { use } from 'react'
 
function MessageComponent({ messagePromise }) {
  const message = use(messagePromise)
  const theme = use(ThemeContext)
  // ...
}

Unlike useContext, use can be called in conditionals and loops:

function HorizontalRule({ show }) {
  if (show) {
    const theme = use(ThemeContext)
    return <hr className={theme} />
  }
  return null
}

Like useContext, use(context) always looks for the closest context provider above the component that calls it. It searches upwards and does not consider context providers in the component from which you’re calling use(context).


use client & use server Directives

React 19 expands support for server components and directives.

  • Use use client to mark a file as a client component.
  • Use use server to mark a file or function as a server action or server component.

This enables:

  • Improved SEO and initial page load times.
  • Direct data fetching and mutation on the server.
  • Seamless integration between client and server logic.

Note: You need a Node.js (or Deno, Bun) server to use the use server1 directive.


Actions

Actions are a new way to handle form submissions and imperative mutations in React, both on the client and the server.

<form action={search}>
  <input name="query" />
  <button type="submit">Search</button>
</form>
  • Actions can be synchronous or asynchronous.
  • Define them on the client with JavaScript or on the server with the use server directive.
  • React manages the data submission lifecycle, providing hooks like useFormStatus and useFormState to access the current state and response.
  • Actions are submitted within a transition, keeping the UI responsive.

Example with optimistic UI:

const [state, formAction] = useFormState(reducer, initialState)
 
<form action={formAction}>
  <input name="todo" />
  <button type="submit">Add</button>
</form>

useOptimistic

useOptimistic is a new hook for managing optimistic UI updates. It lets you apply temporary updates to the UI that are automatically reverted or confirmed once the server responds.

  • Works with both client and server actions.
  • Supports async/await and transitions.
  • Great for forms, lists, and any UI where you want to show immediate feedback.

Example:

const [optimisticTodos, addOptimisticTodo] = useOptimistic(
  todos,
  (state, newTodo) => [...state, newTodo],
)
 
function handleAdd(newTodo) {
  addOptimisticTodo(newTodo)
  // submit to server...
}

Document Metadata

React 19 adds built-in support for managing document metadata such as <title>, <meta>, and <link> tags.

  • Works consistently across client-side, SSR, and RSC environments.
  • No need for third-party libraries for basic metadata management.

Example:

<title>My Page Title</title>
<meta name="description" content="A description of my page." />

Asset Loading

Suspense is now integrated with the loading lifecycle of resources such as stylesheets, fonts, and scripts.

  • React takes these into account to determine when content is ready to display.
  • New Resource Loading APIs like preload and preinit provide more control over resource loading and initialization.
  • Improved support for streaming and progressive hydration.

Other Changes & Features

  • Refs as Props: You can now pass ref as a regular prop, eliminating the need for forwardRef in many cases.
  • Improved Web Components Support: Better integration and event handling.
  • Simplified Context: <Context.Provider> can be replaced with <Context> for cleaner code.
  • Concurrent Rendering Improvements: More reliable and predictable concurrent features.
  • Better Error Handling: Improved error boundaries and stack traces.

Migration & Compatibility

  • Most existing React code will continue to work.
  • The compiler is opt-in and will be rolled out gradually.
  • Legacy hooks (useMemo, useCallback, memo) are still supported for backward compatibility.
  • Some new features (like server actions) require a compatible server environment.

Further Reading

Footnotes

  1. See the caveats