Complete API table
Complete API table in the React to ShadowJS guide.
The table maps React 19 APIs to ShadowJS. Renamed APIs keep the same role; replaced APIs use a different model. Unavailable features are marked explicitly, with the relevant behavior explained in the sections below.
| React 19 export | ShadowJS | Status |
|---|---|---|
useState |
useSignal from @shadow-js/core |
RENAMED |
useReducer |
useReducer(reducer, initial) |
NEW |
useContext |
useContext(Ctx) |
SAME |
useRef |
plain let, or createRef() for elements |
RECIPE |
useEffect |
useEffect(fn), useEffect(deps, fn, { defer }) |
SAME |
useLayoutEffect |
useRenderEffect(compute, apply) |
RENAMED |
useInsertionEffect |
useRenderEffect |
RENAMED |
useImperativeHandle |
useImperativeHandle(ref, create) |
NEW |
useMemo |
useMemo(fn, { equals, lazy, name }) |
SAME |
useCallback |
plain function | RECIPE |
useDebugValue |
name option on hooks; devtools hook |
RECIPE |
useDeferredValue |
useDeferredValue(source, options?) |
SAME |
useTransition |
useTransition() returns [isPending, start] |
SAME |
useId |
useId() |
SAME |
useSyncExternalStore |
useExternalStore(subscribe, getSnapshot, { getServerSnapshot }) |
RENAMED |
useActionState |
useAction(action, initialState) returns [state, dispatch, pending] |
RENAMED |
useOptimistic |
useOptimistic(source, reducer) |
PARTIAL |
useEffectEvent |
useEvent(handler) |
RENAMED |
use (promise or context) |
useContext(Ctx); useResource(...) |
RECIPE |
useFormStatus (react-dom) |
not in core/web; @shadow-js/forms state |
REJECTED |
Fragment (<>) |
Fragment from @shadow-js/web (fragments are compile-time arrays) |
SAME |
Suspense |
Suspense |
SAME |
StrictMode |
none | REJECTED |
Profiler |
devtools hook (DEVTOOLS_EVENT) |
REJECTED |
Activity |
<Activity mode="visible" | "hidden"> |
NEW |
ViewTransition |
startViewTransition(update) helper |
PARTIAL |
Children namespace (see A-07 below) |
children(...) helper methods |
RENAMED |
Component (class) |
function components | REJECTED |
PureComponent (class) |
function components | REJECTED |
lazy |
lazy from @shadow-js/web |
PARTIAL |
memo |
none (components run once) | RECIPE |
forwardRef |
ref is a prop; createRef and useImperativeHandle |
RECIPE |
createContext |
createContext(default); <Ctx value={v}>; Ctx.Provider |
SAME |
createContext |
createContext |
SAME |
createRef |
createRef<T>() (callable and .current) |
NEW |
forwardRef |
none (see R-C12) | RECIPE |
memo |
none (see R-C11) | RECIPE |
lazy |
lazy |
SAME |
startTransition |
startTransition(fn) |
SAME |
Children.count / Children.map / Children.forEach / Children.only / Children.toArray |
children(() => props.children) with count(), map(), forEach(), only(), toArray() |
NEW |
cloneElement |
mergeProps in a wrapper component |
RECIPE |
createElement |
JSX (compiler output) | REJECTED |
createFactory (legacy) |
none | REJECTED |
isValidElement |
node instanceof Node |
RECIPE |
cache |
cache(fn, { limit }) |
NEW |
cacheSignal (RSC) |
none | REJECTED |
captureOwnerStack |
none | REJECTED |
addTransitionType |
none | NOT-1.0 |
act (from react, and react-dom/test-utils) |
act(callback) from @shadow-js/testing |
NEW |
use (see R-H19) |
see R-H19 | RECIPE |
version |
none (use the package version) | REJECTED |
__CLIENT_INTERNALS / unstable internals |
none | REJECTED |
createPortal |
Portal from @shadow-js/web |
RENAMED |
flushSync |
flushSync from @shadow-js/core |
SAME |
unstable_batchedUpdates |
batch |
RENAMED |
preconnect |
preconnect(href, { crossOrigin }) |
NEW |
prefetchDNS |
prefetchDNS(href) |
NEW |
preload |
preload(href, { as, type, media, crossOrigin }) |
NEW |
preloadModule |
preloadModule(href, { crossOrigin }) |
NEW |
preinit |
preinit(href, { as: "style" or "script" }) |
NEW |
preinitModule |
preinitModule(href, { crossOrigin }) |
NEW |
useFormStatus |
see R-H20 | REJECTED |
createRoot (client) |
render(() => <App />, container) |
RENAMED |
hydrateRoot |
hydrate(() => <App />, container, { renderId, data }) |
RENAMED |
root.render(element) |
the function passed to render, or a signal |
RENAMED |
root.unmount() |
the dispose function returned by render |
RENAMED |
render (legacy) |
render |
RENAMED |
hydrate (legacy) |
hydrate |
RENAMED |
findDOMNode |
none | REJECTED |
unmountComponentAtNode |
dispose function | REJECTED |
version (react-dom) |
none | REJECTED |
react-dom/client createRoot / hydrateRoot |
render / hydrate |
RENAMED |
renderToString |
renderToString (@shadow-js/web/server) |
SAME |
renderToStaticMarkup |
renderToString |
PARTIAL |
renderToReadableStream |
renderToStream (Web stream) |
RENAMED |
renderToPipeableStream |
renderToStream(...).pipe(writable) |
PARTIAL |
renderToNodeStream (legacy) |
none | REJECTED |
renderToStaticNodeStream (legacy) |
none | REJECTED |
prerender |
none in core/web; Dusk static output | DEFERRED |
prerenderToNodeStream |
none | DEFERRED |
resume |
none | REJECTED |
resumeToPipeableStream |
none | REJECTED |
renderToStringAsync (Solid; listed for the server row) |
renderToStringAsync |
PARTIAL |
react/jsx-runtime jsx, jsxs, Fragment |
@shadow-js/web/jsx-runtime |
SAME |
react/jsx-dev-runtime jsxDEV |
@shadow-js/web/jsx-dev-runtime |
SAME |
ref as a prop, cleanup returned from a ref callback |
ref={...} (compiled); cleanup through use() |
NEW |
<title>, <meta>, <link>, <style> in the tree (metadata hoisting) |
Title, Meta, Link, Style, Base and useHead |
SAME |
Form action prop (<form action={fn}>) |
useAction in components; form state in @shadow-js/forms |
PARTIAL |
useId in the context of SSR keys |
useId |
SAME |