Skip to main content
@dynamic-labs-sdk/react-hooks is a thin React layer over @dynamic-labs-sdk/client. It exposes a <DynamicProvider> and a set of hooks that subscribe to client state and re-render your components when that state changes.
The JavaScript SDK is headless — there is no built-in modal, wallet picker, or login form. You build all UI yourself. See the JavaScript SDK Overview for details.
New to the hooks? Read How React Hooks Work first — it covers the naming rule (each client function maps to a same-named use hook), which functions get a hook, and the three shapes a hook can take (query, mutation, state). This page is the reference for setup and the headline state hooks.

Installation

The package has @dynamic-labs-sdk/client, @tanstack/react-query, and react as peer dependencies. Install @tanstack/react-query alongside @dynamic-labs-sdk/react-hooks — every state, query, and mutation hook uses TanStack Query internally.

Setup

Wrap your app in QueryClientProvider and DynamicProvider. DynamicProvider passes the client instance you created with createDynamicClient to hooks via React context. QueryClientProvider is required separately — DynamicProvider does not include it. Mount QueryClientProvider outside DynamicProvider:
Any hook used outside a DynamicProvider throws MissingProviderError. Any hook used outside a QueryClientProvider throws No QueryClient set, use QueryClientProvider to set one.

State hooks

These hooks read directly from the client and re-render the component when the underlying state changes. Like all hooks in this package, they return the full TanStack Query result ({ data, isLoading, error, refetch, … }). They have no parameters. Each state hook returns the full react-query result — { data, isLoading, error, refetch, ... } — so the value you want lives on data. Destructure it: const { data: user } = useUser(). The descriptions below refer to what data holds.

useUser

data is the current authenticated user, or null if no user is signed in. Re-renders on sign-in, sign-out, and profile updates.

useGetWalletAccounts

Returns all wallet accounts on the current session, verified and unverified. Re-renders when accounts are added, removed, or verified.

useGetUserSocialAccounts

Returns the user’s linked social accounts (SocialAccount[]). Re-renders when the user changes. Empty array when no user is signed in.
See Social Account Linking for the management APIs.

useGetAvailableWalletProvidersData

Returns the wallet providers available to connect and their metadata (WalletProviderData[]). Re-renders when the available providers change (for example on a network switch).

useInitStatus

Returns the client’s initialization status: 'uninitialized' | 'in-progress' | 'finished' | 'failed'. Use this to gate UI that depends on SDK methods until the client is ready.
See Initializing the Dynamic Client for init-status semantics.

useSessionExpiresAt

Returns the session expiration Date, or null if there is no active session. Re-renders on session updates.

Event hook

useOnEvent

Subscribes to any client event for the lifetime of the component. The subscription is cleaned up on unmount or when the event name changes. The listener is wrapped in a ref, so updating its identity between renders does not re-subscribe.
The listener signature is inferred from the event name. See the Events Catalog for the full event surface. For state-change events (userChanged, walletAccountsChanged, tokenChanged, etc.) prefer the dedicated state hooks above — they subscribe for you and avoid manual subscription bookkeeping.

Client access

useDynamicClient

Returns the DynamicClient instance from context. Throws MissingProviderError if used outside a DynamicProvider. Most code should not need this — use the state hooks for reactive state, and import client functions directly (signMessage, getMultichainTokenBalances, etc.) for one-shot calls.

Multiple clients

If your app uses more than one Dynamic client, mount a separate DynamicProvider for each subtree. Hooks resolve the closest provider, so state from one client never leaks into a tree wrapped in a different one.
Last modified on July 7, 2026