Hooks and APIs at a glance
Imports come from @shadow-js/core unless the table says @shadow-js/web.
Imports come from @shadow-js/core unless the table says @shadow-js/web.
| React | ShadowJS | Import | Notes |
|---|---|---|---|
useState |
useStore |
@shadow-js/core |
State |
useReducer |
useReducer |
@shadow-js/core |
Same name and shape: [state, dispatch]. Redux and Zustand |
useEffect |
useEffect, onMount, onCleanup |
@shadow-js/core |
Dependencies are tracked automatically. Effects |
useLayoutEffect |
useRenderEffect |
@shadow-js/core |
Runs in the render phase, before user effects in the same flush. Effects |
useMemo |
useMemo, or a plain const |
@shadow-js/core |
Derived values |
useCallback |
Not needed | Handlers are created once | |
useRef (DOM) |
A let variable and ref |
Refs | |
useRef (mutable value) |
A let variable, or useStore if it drives the UI |
The body runs once, so a variable persists | |
useContext, createContext |
useContext, createContext |
@shadow-js/core |
useContext throws without a provider and without a default. Context |
useId |
useId |
@shadow-js/core |
Throws outside an owner; same value on server and client |
useSyncExternalStore |
useExternalStore |
@shadow-js/core |
Same arguments, plus getServerSnapshot for the server. Redux and Zustand |
useTransition, useDeferredValue, startTransition |
Same names | Implemented in 1.0 (2026-10-09). See Transitions. | |
useOptimistic |
useOptimistic |
@shadow-js/core |
Different signature. Async data |
use(promise) |
useResource read inside Suspense |
@shadow-js/core, @shadow-js/web |
Async data |
use(context) |
useContext |
@shadow-js/core |
|
Suspense |
Suspense |
@shadow-js/web |
|
lazy |
lazy |
@shadow-js/web |
Has preload() |
memo |
Not needed | memo exported by @shadow-js/web is the compiler's useMemo helper, not React.memo |
|
forwardRef |
Not needed: props.ref |
Refs | |
useImperativeHandle |
None | Pass callbacks as props | |
createPortal |
Portal |
@shadow-js/web |
Portals |
StrictMode |
None | Nothing runs twice, so there is nothing to detect | |
| Error boundary class | ErrorBoundary |
@shadow-js/web |
Error boundaries |
<>...</> and Fragment |
<>...</> and Fragment |
@shadow-js/web |
|
Children.map, cloneElement |
children(() => props.children) |
@shadow-js/core |
Resolves children once; toArray() |
flushSync (react-dom) |
flushSync |
@shadow-js/core |
Also batch |
dangerouslySetInnerHTML |
dangerouslySetInnerHTML={{ __html }} or innerHTML={html} |
A property write of the markup. Trusted HTML only | |
ReactDOM.createRoot(el).render(...) |
render(() => <App />, el) |
@shadow-js/web |
Returns a dispose function |
hydrateRoot |
hydrate(() => <App />, el, { data }) |
@shadow-js/web |
Next.js page |