Published 2 Aug 2025 · Updated 11 Jul 2026
React 19.2: Features, Stable Release Date & Upgrade Guide
React 19 became stable on December 5, 2024. React 19.1 followed in June 2025, and React 19.2 arrived on October 1, 2025. This guide separates the features in the original stable release from the APIs added later, then turns the release notes into a practical React 18 to React 19 upgrade checklist.Quick answer: is React 19 stable?
- Stable release: December 5, 2024.
- Current scope of this guide: React 19 through React 19.2.
- Main React 19 additions: Actions, form APIs, useOptimistic, use, ref as a prop, better hydration errors, and resource handling.
- Main React 19.2 additions: Activity, useEffectEvent, cacheSignal, Performance Tracks, Partial Pre-rendering, and SSR refinements.
React 19 release timeline
React 19 was first discussed as a release candidate, but the stable release date is December 5, 2024. React 19.1 shipped in June 2025, followed by React 19.2 on October 1, 2025. That distinction matters: APIs such as useActionState belong to the original React 19 release, while Activity and useEffectEvent are React 19.2 features.
Actions and form APIs in React 19
An Action is an async function used inside a transition or passed to a form action. React coordinates the pending state, error flow, form submission, and optimistic UI around that work. The most useful pieces areuseActionState, form Actions, useFormStatus, and useOptimistic.A TypeScript form with useActionState
"use client";
import { useActionState } from "react";
import { useFormStatus } from "react-dom";
type FormState = { error: string | null; saved: boolean };
async function saveName(
previousState: FormState,
formData: FormData,
): Promise<FormState> {
const name = String(formData.get("name") ?? "").trim();
if (name.length < 2) {
return { error: "Enter at least two characters.", saved: false };
}
await updateProfile({ name });
return { error: null, saved: true };
}
function SubmitButton() {
const { pending } = useFormStatus();
return <button disabled={pending}>{pending ? "Saving..." : "Save"}</button>;
}
export function ProfileForm() {
const [state, formAction] = useActionState(saveName, {
error: null,
saved: false,
});
return (
<form action={formAction}>
<input name="name" aria-describedby="name-status" />
<SubmitButton />
<p id="name-status" aria-live="polite">
{state.error ?? (state.saved ? "Profile saved." : "")}
</p>
</form>
);
}Optimistic UI with useOptimistic
useOptimistic lets the interface show the expected result while an Action is running. When the request finishes or fails, React returns to the value supplied by the parent. Keep the server response as the source of truth and make the pending state visible instead of pretending the request already succeeded.Build with Actions, not just release notes
The API list becomes useful when it solves a real failure path. TheuseActionState form validation guide returns typed field errors, preserves safe submitted values, and handles pending submissions. TheuseOptimistic rollback guide keeps the confirmed server value separate from a temporary UI preview when an API request fails.Core React 19 changes worth using
The use API
use reads a resource during render. It can read a Promise supplied by a Suspense-compatible framework or library, and it can read context conditionally. Do not create a new Promise in a Client Component render and immediately pass it to use; React warns because that Promise is not cached.Ref as a prop
Function components can receiveref as a prop, so new components no longer need forwardRef. React has stated that it plans to deprecate forwardRef in a future release; that is different from saying it is already unavailable.type InputProps = React.ComponentPropsWithoutRef<"input"> & {
ref?: React.Ref<HTMLInputElement>;
};
function SearchInput({ ref, ...props }: InputProps) {
return <input ref={ref} {...props} />;
}Context providers and ref cleanup
React 19 allows<ThemeContext value="dark">instead of <ThemeContext.Provider>. Ref callbacks can also return cleanup functions. Because a returned value may now be treated as cleanup, TypeScript can reject implicit callback returns such as ref={node => (instance = node)}.Hydration error diffs
React 19 combines several vague hydration warnings into a more useful mismatch report. The diff can point to non-deterministic values, locale-dependent formatting, invalid HTML nesting, or a server/client branch. Fix the differing render input rather than suppressing the warning.Document metadata, styles, and resources
React can hoisttitle, meta, and link elements into the document head. It also coordinates stylesheet precedence and resource hints with rendering. Framework metadata systems can still provide route-level merging, defaults, and other conveniences.What React 19.2 adds
The following APIs were not part of the December 2024 stable release. They arrived with React 19.2 in October 2025.Activity
Activity can keep a hidden part of the UI mounted while deferring its updates and unmounting its Effects. This can preserve state for a view the user may return to without giving hidden work the same priority as visible content.<Activity mode={isVisible ? "visible" : "hidden"}>
<SettingsPanel />
</Activity>useEffectEvent
useEffectEvent separates event-like logic from the reactive setup of an Effect. It is useful when a callback needs the latest props or state but should not reconnect an external system. It is not a general escape hatch for removing dependencies.const onConnected = useEffectEvent(() => {
showNotification("Connected", theme);
});
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.on("connected", onConnected);
connection.connect();
return () => connection.disconnect();
}, [roomId]);cacheSignal, Performance Tracks, and Partial Pre-rendering
cacheSignal lets React Server Component work stop when a cache lifetime ends. React Performance Tracks add React-specific scheduling and component information to Chrome DevTools profiles. React 19.2 also adds primitives that let frameworks pre-render a static shell and resume the postponed work later. These server features still need framework or bundler integration.React Server Components are not automatic SSR
React 19 makes the public Server Component feature set available to frameworks, but it does not turn a client-only React application into a server-rendered application by itself. A framework or bundler must implement the server/client module graph, transport, routing, caching, and deployment behavior. If you use the App Router, ourNext.js 16 guide explains the surrounding framework model.React 18 to React 19 upgrade checklist
Before changing production dependencies
- Start with React 18.3: It behaves like React 18.2 while warning about APIs affected by React 19.
- Check framework and library peer dependencies: Upgrade packages that do not yet accept React 19.
- Run the official codemods: Review every change instead of treating the output as a finished migration.
- Update React and React DOM together: Keep their major and minor versions aligned.
- Update TypeScript types: Upgrade @types/react and @types/react-dom with the runtime packages.
- Exercise forms and optimistic states: Test success, validation errors, rejected requests, and repeated submissions.
- Review ref callbacks: Replace unintended implicit return values and test cleanup behavior.
- Test hydration and streaming: Include production-like SSR, locale, time, browser-extension, and slow-network cases.
npm install react@19 react-dom@19
npm install --save-dev @types/react@19 @types/react-dom@19
Common React 19 migration pitfalls
- Using the Canary name useFormState: The stable React API is useActionState; useFormState was its earlier Canary name.
- Removing every forwardRef immediately: Existing code can migrate gradually; new function components can accept ref as a prop.
- Using useEffectEvent to silence the hooks linter: Effect Events are only for event-like logic fired by an Effect.
- Creating a Promise during Client Component render: Pass a cached Promise from a compatible framework or data layer to use.
- Treating Server Components as a standalone switch: Confirm what your framework and deployment target actually support.