@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. 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>
);
}4. 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 |
5. 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
6. 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>;
}7. 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]);
// ...
}8. 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