@mysten/dapp-kit
This guide helps you migrate from the original @mysten/dapp-kit (legacy) to the new
@mysten/dapp-kit-react package.
The legacy @mysten/dapp-kit package will continue to work with the latest SDK, but it only
supports JSON-RPC and will not receive further updates. We recommend migrating to
@mysten/dapp-kit-react for new features and gRPC support.
Overview
The new dApp Kit SDK represents a complete rewrite with these key changes:
- Framework agnostic: Split into
@mysten/dapp-kit-core(framework-agnostic) and@mysten/dapp-kit-react(React bindings) - No React Query dependency: Direct promise-based API instead of mutation hooks
- Web Components: UI components built with Lit Elements for cross-framework compatibility
- Smaller bundle size: No React Query dependency, lighter state management with nanostores
- Better SSR support: Compatible with SSR frameworks like Next.js
- Cross-framework compatibility: Core functionality can be used in vanilla JS, Vue, React, and other frameworks
Step-by-Step Migration
1. Update Dependencies
Remove the old package and install the new ones:
npm uninstall @mysten/dapp-kit
npm i @mysten/dapp-kit-react @mysten/dapp-kit-core @mysten/sui2. Create dApp Kit Instance
Create a new instance of the dApp Kit using the createDAppKit function and register the global
type.
// dapp-kit.ts
import { createDAppKit } from '@mysten/dapp-kit-react';
import { SuiGrpcClient } from '@mysten/sui/grpc';
const GRPC_URLS = {
testnet: 'https://fullnode.testnet.sui.io:443',
};
export const dAppKit = createDAppKit({
networks: ['testnet'],
createClient(network) {
return new SuiGrpcClient({ network, baseUrl: GRPC_URLS[network] });
},
});
// global type registration necessary for the hooks to work correctly
declare module '@mysten/dapp-kit-react' {
interface Register {
dAppKit: typeof dAppKit;
}
}3. Register Types
The declare module block in the previous step registers your dApp Kit instance's type globally.
This enables all hooks like useDAppKit(), useCurrentNetwork(), and useCurrentClient() to
automatically infer the correct types based on your configuration (e.g., your specific networks and
client type).
declare module '@mysten/dapp-kit-react' {
interface Register {
dAppKit: typeof dAppKit;
}
}Without this registration, hooks return generic types and you lose type safety for things like
network names. If you prefer not to use global type registration, you can pass the dAppKit
instance explicitly to each hook instead:
const connection = useWalletConnection({ dAppKit });
const network = useCurrentNetwork({ dAppKit });4. Replace Provider Setup
Replace the nested dApp Kit providers with a single unified provider. You can keep your existing
QueryClientProvider for data fetching.
// App.tsx
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
- import { SuiClientProvider, WalletProvider } from '@mysten/dapp-kit';
+ import { DAppKitProvider } from '@mysten/dapp-kit-react';
+ import { dAppKit } from './dapp-kit.ts';
export function App() {
const queryClient = new QueryClient();
- const networkConfig = {
- mainnet: { url: 'https://mainnet.sui.io:443' },
- testnet: { url: 'https://testnet.sui.io:443' },
- };
return (
<QueryClientProvider client={queryClient}>
- <SuiClientProvider networks={networkConfig} defaultNetwork="mainnet">
- <WalletProvider>
- <App />
- </WalletProvider>
- </SuiClientProvider>
+ <DAppKitProvider dAppKit={dAppKit}>
+ <App />
+ </DAppKitProvider>
</QueryClientProvider>
);
}5. Configuration Option Changes
The createDAppKit function has different configuration options than the old WalletProvider:
Old (WalletProvider) | New (createDAppKit) | Notes |
|---|---|---|
| - | networks (required) | List of network identifiers your app supports |
| - | createClient | Function to create a client for each network |
| - | defaultNetwork | Network to use by default (defaults to first in networks) |
autoConnect (false) | autoConnect (true) | Default changed from false to true |
enableUnsafeBurner | enableBurnerWallet | Renamed |
slushWallet | slushWalletConfig | Renamed |
storage | storage | Unchanged |
storageKey | storageKey | Unchanged |
preferredWallets | - | Removed |
walletFilter | - | Removed (wallets filtered by network compatibility) |
theme | - | Removed (UI components are now web components with built-in styling) |
| - | walletInitializers | New option for registering custom wallets |
6. Update Hook Usage
The new dApp Kit has a dramatically simplified hook API. Most hooks from the original version have
been replaced with direct action calls through useDAppKit().
Available hooks in the new version:
useDAppKit()- Access the dAppKit instance for calling actionsuseCurrentClient()- Get the blockchain client (renamed fromuseSuiClient)useCurrentAccount()- Get the current connected accountuseCurrentWallet()- Get the current connected walletuseWallets()- Get the list of available walletsuseWalletConnection()- Get the current wallet connection statususeCurrentNetwork()- Get the current network
Removed hooks:
All wallet action hooks have been replaced with direct action calls via useDAppKit():
useConnectWallet-> UsedAppKit.connectWallet()useDisconnectWallet-> UsedAppKit.disconnectWallet()useSignTransaction-> UsedAppKit.signTransaction()useSignAndExecuteTransaction-> UsedAppKit.signAndExecuteTransaction()useSignPersonalMessage-> UsedAppKit.signPersonalMessage()useSwitchAccount-> UsedAppKit.switchAccount()
All data fetching hooks have been removed (giving you flexibility to use your preferred solution):
useSuiClientQuery-> UseuseCurrentClient()with your data fetching solutionuseSuiClientMutation-> UseuseCurrentClient()with your data fetching solutionuseSuiClientInfiniteQuery-> UseuseCurrentClient()with your data fetching solutionuseSuiClientQueries-> UseuseCurrentClient()with your data fetching solutionuseResolveSuiNSNames-> UseuseCurrentClient()directly
Other removed hooks:
useAutoConnectWallet-> Auto-connect is enabled by defaultuseAccounts-> UseuseWalletConnection()to accessconnection.wallet.accountsuseWalletStore-> Use specific hooks likeuseWalletConnection()instead
7. Replace Mutation Patterns
The built-in mutation hooks have been removed. Use TanStack Query's useMutation with
useDAppKit() to get similar functionality.
Chain parameter replaced with network:
In the old dapp-kit, you could optionally pass a chain parameter (e.g., sui:mainnet) to methods
like signTransaction and signAndExecuteTransaction. In the new dapp-kit, use the network
parameter instead - the chain is automatically derived from the network.
- const { mutateAsync: signAndExecute } = useSignAndExecuteTransaction();
- await signAndExecute({ transaction, chain: 'sui:mainnet' });
+ const dAppKit = useDAppKit();
+ await dAppKit.signAndExecuteTransaction({ transaction, network: 'mainnet' });Mutation example:
- import { useSignAndExecuteTransaction } from '@mysten/dapp-kit';
+ import { useMutation } from '@tanstack/react-query';
+ import { useDAppKit } from '@mysten/dapp-kit-react';
import type { Transaction } from '@mysten/sui/transactions';
export function ExampleComponent({ transaction }: { transaction: Transaction }) {
- const { mutateAsync: signAndExecute } = useSignAndExecuteTransaction();
+ const dAppKit = useDAppKit();
+
+ const { mutateAsync: signAndExecute } = useMutation({
+ mutationFn: (tx: Transaction) => dAppKit.signAndExecuteTransaction({ transaction: tx }),
+ });
const handleClick = async () => {
- await signAndExecute(
- { transaction },
- {
- onSuccess: (result: any) => console.log(result),
- onError: (error: any) => console.error(error),
- },
- );
+ await signAndExecute(transaction, {
+ onSuccess: (result) => console.log(result),
+ onError: (error) => console.error(error),
+ });
};
return <button onClick={handleClick}>Sign and Execute</button>;
}Alternative: Direct promise-based calls
If you don't need React Query's state management, you can call dAppKit methods directly:
import { useDAppKit } from '@mysten/dapp-kit-react';
import type { Transaction } from '@mysten/sui/transactions';
export function ExampleComponent({ transaction }: { transaction: Transaction }) {
const dAppKit = useDAppKit();
const handleClick = async () => {
try {
const result = await dAppKit.signAndExecuteTransaction({ transaction });
console.log(result);
} catch (error) {
console.error(error);
}
};
return <button onClick={handleClick}>Sign and Execute</button>;
}8. Replace Data Fetching Patterns
The built-in data fetching hooks have been removed. Use TanStack Query's useQuery with
useCurrentClient() to get similar functionality:
- import { useSuiClientQuery } from '@mysten/dapp-kit';
+ import { useQuery } from '@tanstack/react-query';
+ import { useCurrentClient } from '@mysten/dapp-kit-react';
export function ExampleComponent({ objectId }: { objectId: string }) {
+ const client = useCurrentClient();
+
- const { data, isLoading, error } = useSuiClientQuery('getObject', {
- id: objectId,
- });
+ const { data, isLoading, error } = useQuery({
+ queryKey: ['object', objectId],
+ queryFn: () => client.core.getObject({ objectId }),
+ });
// ...
}Alternative: Direct data fetching
If you don't need React Query's caching and state management, you can fetch data directly:
import { useCurrentClient } from '@mysten/dapp-kit-react';
import { useState, useEffect } from 'react';
export function ExampleComponent({ objectId }: { objectId: string }) {
const client = useCurrentClient();
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
client.core
.getObject({ objectId })
.then((result) => setData(result.object ?? null))
.catch((err) => setError(err.message))
.finally(() => setIsLoading(false));
}, [client, objectId]);
// ...
}9. Update The Remaining Code
The following hooks from the original dApp Kit are not available anymore:
useSuiClientQuery→ UseuseQueryfrom@tanstack/react-queryuseSuiClientMutation→ UseuseMutationfrom@tanstack/react-queryuseSuiClientInfiniteQuery→ UseuseInfiniteQueryfrom@tanstack/react-queryuseResolveSuiNSNames→ UseuseCurrentClient()with the suins extension
The reportTransactionEffects feature is planned for deprecation in the Wallet
Standard and so the dApp Kit provides no
replacement.
The following have been removed:
useReportTransactionEffectshookreportTransactionEffectscallback fromuseSignTransaction- Automatic transaction effects reporting from
useSignAndExecuteTransaction
CSS and Theming Changes
The new dApp Kit no longer bundles a CSS file. If you were importing the old CSS file, remove the import:
- import '@mysten/dapp-kit/dist/full/index.css';The new dApp Kit uses web components with built-in styling that can be customized using CSS custom properties. See the Theming documentation for details on customizing the appearance of dApp Kit components.
Quick theme setup:
:root {
--primary: #4f46e5;
--primary-foreground: #ffffff;
--background: #ffffff;
--foreground: #0f172a;
--border: #e2e8f0;
--radius: 0.5rem;
}Removing TanStack Query
If you were only using @tanstack/react-query for dApp Kit and don't need it for other parts of
your application, you can now remove it:
npm uninstall @tanstack/react-query