Component API
memo
function memo<P>(
component: (props: P) => VNode,
compare?: (prevProps: P, nextProps: P) => boolean,
): MemoComponentFnReturns a memoized version of the component that skips re-rendering when props are shallowly equal. Pass a custom compare function for fine-grained control.
forwardRef
function forwardRef<T, P>(
render: (props: P, ref: RefObject<T>) => VNode,
): (props: P & { ref?: RefObject<T> }) => VNodeCreates a component that forwards the ref prop to a child element or imperative handle.
lazy
function lazy<P>(
loader: () => Promise<{ default: (props: P) => VNode }>,
): (props: P) => VNodeCreates a lazily loaded component. Must be used with Suspense. The loader function is called on first render and cached thereafter.
ErrorBoundary
<ErrorBoundary
fallback={(error, reset) => (
<div>
<p>Error: {error.message}</p>
<button onClick={reset}>Retry</button>
</div>
)}
>
{children}
</ErrorBoundary>Props:
fallback- A function(error: unknown, reset: () => void) => VNodecalled when an error is caught. Theresetfunction re-renders the children.children- The subtree to monitor for errors
ErrorBoundary + Suspense
Place an ErrorBoundary inside a Suspense boundary to catch errors from lazy-loaded components and rejected promises from use():
<Suspense fallback={<p>Loading...</p>}>
<ErrorBoundary fallback={(err) => <p>Failed: {err.message}</p>}>
<LazyComponent />
</ErrorBoundary>
</Suspense>INFO
An ErrorBoundary wrapping a Suspense boundary cannot catch async rejections from lazy components, because the re-render is triggered by the scheduler (no parent error handler on the stack). The ErrorBoundary-inside-Suspense pattern works correctly.
Suspense
<Suspense fallback={<p>Loading...</p>}>
{children}
</Suspense>Props:
fallback- VNode to render while suspended content is loadingchildren- The subtree that may suspend (vialazyoruse(promise))
Suspense works with:
lazy()components that are still loadinguse(promise)calls with pending promises- Streaming SSR with
renderToReadableStream(sends fallback immediately, swaps in content when ready) - Hydration (handles both streaming placeholders and non-streaming children)
createPortal
function createPortal(children: VNode, container: Element): VNodeRenders children into a DOM node outside the component's parent hierarchy. Events still bubble through the Tachys tree (not the DOM tree).
createRef
function createRef<T = unknown>(): RefObject<T>Creates a { current: null } ref object. Prefer useRef inside components.
StrictMode
Imported from tachys/compat.
import { StrictMode } from "tachys/compat"
<StrictMode>
{children}
</StrictMode>No-op passthrough in Tachys. In React, StrictMode double-invokes render functions and enables additional development warnings. Exported so that <StrictMode> usage in third-party code does not break when aliased to tachys/compat.
Profiler
Imported from tachys/compat.
import { Profiler } from "tachys/compat"
<Profiler id="MyComponent" onRender={onRenderCallback}>
{children}
</Profiler>Props:
id- Identifies the part of the tree being profiledonRender- Callback invoked after the profiled subtree commits
No-op passthrough in Tachys. In React, Profiler measures rendering performance and calls onRender with timing data. Exported so that <Profiler> usage in third-party code does not break when aliased to tachys/compat.