facebook/react
react
Active contributors: sebmarkbage, eps1lon, gnoff, acdlite, rickhanlonii
Purpose
packages/react/ is the front door to the runtime. It exports createElement, the built-in hooks (useState, useEffect, useMemo, useTransition, use, useEffectEvent, …), the JSX runtimes, the legacy Component/PureComponent classes, helpers like forwardRef/memo/lazy, the Suspense and Activity symbols, startTransition, cache/cacheSignal, the testing helper act, and the development-only captureOwnerStack.
The package itself does very little work. Hooks are tiny wrappers that read the current dispatcher from ReactSharedInternals. The real implementations of those hooks live in whichever renderer is currently executing — almost always react-reconciler (during a render) or react-server/react-dom's SSR dispatcher (during streaming SSR or RSC).
Directory layout
packages/react/
├── package.json
├── index.js # client entry → src/ReactClient
├── react.react-server.js # react-server entry → src/ReactServer
├── jsx-runtime.js / jsx-dev-runtime.js / *.react-server.js
├── compiler-runtime.js # alias used by output of the React Compiler
└── src/
├── ReactClient.js # client-runtime export list
├── ReactServer.js # server-runtime (RSC) export list
├── ReactBaseClasses.js # Component, PureComponent
├── ReactChildren.js # Children.map/forEach/count/toArray/only
├── ReactContext.js # createContext
├── ReactCreateRef.js # createRef
├── ReactForwardRef.js # forwardRef
├── ReactMemo.js # memo
├── ReactLazy.js # lazy
├── ReactHooks.js # all built-in hook re-exports (route through dispatcher)
├── ReactStartTransition.js # startTransition / startGestureTransition
├── ReactTransitionType.js # addTransitionType
├── ReactOwnerStack.js # captureOwnerStack (dev-only)
├── ReactCacheClient.js / ReactCacheImpl.js / ReactCacheServer.js # cache(), cacheSignal()
├── ReactSharedInternalsClient.js # the dispatcher / current owner / etc. (client)
├── ReactSharedInternalsServer.js # the dispatcher (server / RSC)
├── ReactCompilerRuntime.js # the runtime helpers the compiler emits calls to
├── ReactAct.js # act() — flushes work for tests
├── ReactTaint.js / ReactTaintRegistry.js # taintObjectReference / taintUniqueValue
└── jsx/ # JSX runtime (react/jsx-runtime, react/jsx-dev-runtime)Key abstractions
| Symbol | File | Description |
|---|---|---|
createElement(type, props, ...children) |
packages/react/src/jsx/ReactJSXElement.js |
Constructs a React element. Output of legacy JSX. |
jsx, jsxs, jsxDEV |
packages/react/src/jsx/ReactJSXElement.js |
The new JSX runtime entry points (react/jsx-runtime). |
useState, useEffect, useMemo, ... |
packages/react/src/ReactHooks.js |
Routes through ReactCurrentDispatcher.current.useX(...). |
use(promise) / use(context) |
packages/react/src/ReactHooks.js |
The unified primitive for awaiting promises/contexts inside render. |
useEffectEvent(fn) |
packages/react/src/ReactHooks.js |
Non-reactive event hook — callback identity is stable but always reads latest closures. |
cache(fn) |
packages/react/src/ReactCacheClient.js / ReactCacheImpl.js |
Per-render memoization for RSC. The client export throws unless the compiler is enabled. |
cacheSignal() |
packages/react/src/ReactCacheClient.js |
An AbortSignal that fires when the surrounding cache() lifetime ends. New in 19.2. |
forwardRef(Component) |
packages/react/src/ReactForwardRef.js |
Wraps a function component so it accepts a ref. Largely unnecessary in React 19+ where ref is just a prop on function components. |
memo(Component, areEqual?) |
packages/react/src/ReactMemo.js |
Shallow-compares props to skip re-renders. |
lazy(loader) |
packages/react/src/ReactLazy.js |
Suspense-backed code splitting. |
Component, PureComponent |
packages/react/src/ReactBaseClasses.js |
The class API. Largely frozen — most new work happens in hooks. |
Children |
packages/react/src/ReactChildren.js |
The Children.map/.forEach/.count/.toArray/.only helpers. |
createContext(default) |
packages/react/src/ReactContext.js |
Context object (Provider / Consumer / _currentValue). |
act(callback) |
packages/react/src/ReactAct.js |
Test helper: flushes all scheduled work and returns when settled. Removed from production builds in 19.1. |
startTransition(fn) / startGestureTransition(fn) |
packages/react/src/ReactStartTransition.js |
Marks updates inside fn as low-priority transitions. |
addTransitionType(type) |
packages/react/src/ReactTransitionType.js |
Tags the next transition for view-transition matching. |
captureOwnerStack() |
packages/react/src/ReactOwnerStack.js |
Dev-only — returns a string snapshot of the current Owner Stack. |
taintObjectReference, taintUniqueValue |
packages/react/src/ReactTaint.js |
RSC-only — marks values that must not be sent to the client. |
How it works
graph TD UserCode[User code: const [s, setS] = useState(0)] -->|useState(0)| ReactHooks[react/src/ReactHooks.js useState] ReactHooks -->|reads current dispatcher| Internals[ReactSharedInternalsClient.H] Internals -->|installed by| Reconciler[react-reconciler ReactFiberHooks: HooksDispatcherOnMount/Update/...] Reconciler -->|or while streaming| FizzServer[react-server ReactFizzHooks] Reconciler -->|on RSC server| FlightServer[react-server ReactFlightHooks]
ReactSharedInternals is a module-level object exported from packages/react/src/ReactSharedInternalsClient.js (and ReactSharedInternalsServer.js for the react-server condition). It's the only state react itself owns at runtime: the current dispatcher (H), the current owner (A), the current transition (T), and a small bag of dev-only helpers. Every renderer mutates this object as it enters/leaves a render.
This is also how useState outside a component throws "Hooks can only be called inside the body of a function component" — outside any render, the dispatcher is set to a sentinel that throws. The sentinels are in packages/react/src/jsx/ and the matching reconciler code.
Two entry points: client vs server
packages/react/index.js re-exports from src/ReactClient.js. packages/react/react.react-server.js re-exports from src/ReactServer.js. The react-server export condition in package.json is what tells a bundler which one to pick.
The two surfaces differ in what's exported. The server (RSC) entry omits the client-only hooks (useState, useEffect, useLayoutEffect, useImperativeHandle, useTransition, ...) and adds the server-specific ones (cache, taintObjectReference, taintUniqueValue). The shared parts (createElement, Fragment, forwardRef, memo, lazy, Suspense, use) are exported from both.
Integration points
- The reconciler installs/removes its dispatcher on every fiber by mutating
ReactSharedInternals.H(packages/react-reconciler/src/ReactFiberHooks.js). - The DOM SSR runtime swaps in
ReactFizzHooksDispatcherfrompackages/react-server/src/ReactFizzHooks.js. - The Flight (RSC) writer swaps in
ReactFlightHooksDispatcherfrompackages/react-server/src/ReactFlightHooks.js. - The compiler emits calls to runtime helpers in
packages/react/src/ReactCompilerRuntime.js(c(N)for "allocate a memo cache of size N").
Entry points for modification
- Adding a new built-in hook: add the wrapper in
packages/react/src/ReactHooks.js, export it fromReactClient.js/ReactServer.jsas appropriate, then implement it in all dispatchers —packages/react-reconciler/src/ReactFiberHooks.js(mount/update/rerender), the SSR dispatcher inpackages/react-server/src/ReactFizzHooks.js, the Flight dispatcher inpackages/react-server/src/ReactFlightHooks.js. Forgetting one is the most common mistake. - Adding a new top-level export:
packages/react/src/ReactClient.jsis the manifest of what's "client React". Add the export there (and the.react-server.jssibling if it should be available on the server too). - Tweaking what
cache()returns or howcacheSignal()resolves:packages/react/src/ReactCacheImpl.jsis shared between the client and server variants.
Related pages
- react-reconciler — where the real hook implementations live.
- react-server — where the SSR / RSC dispatchers live.
- features/hooks — end-to-end view of how a hook call flows.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.