Skip to main content
This page covers the foundational changes: how you create and provide the SDK, how you read state, and the shift from an event-driven model to an imperative one. Read the migration overview first if you haven’t.

Provider and client

In the React SDK a single DynamicContextProvider created the SDK, held configuration, and exposed everything through useDynamicContext(). In the JavaScript SDK you create the client yourself with createDynamicClient() and, in React, pass it to a thin DynamicProvider. State is read through focused hooks instead of one context object. Create the client once in a module that loads at startup and register your chain extensions. The client initializes itself automatically.
In React, @dynamic-labs-sdk/react-hooks is built on TanStack Query, so a QueryClientProvider must wrap DynamicProvider. See the React Quickstart for the full setup.

Reading state

useDynamicContext() no longer exists. Instead, import the specific hook (React) or read the equivalent property/function on the client instance (vanilla) for the state you need.

Waiting for initialization

The React SDK gated your app behind its own loading state. Now you decide when the client is ready — either await a helper (vanilla) or render off the init status (React).

From events to promises

This is the most important shift. The React SDK was reactive: you subscribed to events (onAuthSuccess, onWalletAdded, …) and the SDK told you when things happened. The JavaScript SDK is imperative: you call a function, and you get the result back directly — from the resolved promise (vanilla) or the hook’s onSuccess/onError callbacks (React). You already know when a flow starts and finishes because you started it. Events still exist for genuinely ambient state changes (a wallet added, a session expiring), but they’re no longer how you observe the outcome of an action you triggered.

Subscribing to the events that remain

When you do want to react to ambient state changes, subscribe with onEvent (vanilla) or useOnEvent (React), which handles cleanup for you.
The core events include initStatusChanged, initErrorChanged, userChanged, tokenChanged, sessionExpiresAtChanged, mfaTokenChanged, projectSettingsChanged, walletAccountsChanged, and logout. The client emits additional events (for example around MFA, checkout, device registration, wallet providers, and flow execution) that follow the same subscribe pattern.

RPC URL overrides

overrideNetworkRpcUrl is gone. Configure RPC URLs (and any other network overrides) with a networksData transformer when you create the client. It receives the full list of networks and returns the list the SDK should use, so you can rewrite, filter, or reorder them in one place — the first network of a chain is the default for wallets with no saved selection, so reordering also sets that default.
See Network transformers for the full API.
Ethers.js is not supported. Migrate wallet/provider code to viem, which the EVM extension returns directly.

See also

Last modified on July 22, 2026