← Back to templates

nextjs

Next.js, Tailwind, @solana/kit wallet + on-chain actions

Preview of nextjs

nextjs

Next.js starter built on @solana/kit v7 with the kit plugin client and @solana/react. Connect a browser wallet, switch networks, and send real transactions — SOL transfers, SPL token actions, and memos — with zero manual pipe() boilerplate.

Getting Started

npx -y create-solana-dapp@latest -t solana-foundation/templates/kit/nextjs
npm install
npm run dev

Open http://localhost:3000, connect a wallet, and (on devnet) click Airdrop 1 SOL to fund it. Then try the actions. Need devnet SOL another way? faucet.solana.com.

What's Included

How it works

The app builds one kit client per selected cluster in app/lib/solana-client.ts and provides it through @solana/react's ClientProvider:

createClient()
  .use(walletSigner({ chain })) // wallet as payer + identity; must precede rpc
  .use(solanaRpc({ rpcUrl, rpcSubscriptionsUrl })) // rpc, subscriptions, getMinimumBalance, sendTransaction
  .use(rpcAirdrop()) // client.airdrop (non-mainnet)
  .use(systemProgram()) // client.system.instructions.transferSol
  .use(tokenProgram()) // client.token.instructions.{createMint,mintToATA,transferToATA}
  .use(memoProgram()); // client.memo.instructions.addMemo

Components read the client with useClient() and the connected wallet with the @solana/kit-plugin-wallet/react hooks (useWallets, useConnect, useConnectedWallet, useDisconnect). Sending is a single call — client.sendTransaction([instruction]) for raw instructions, or client.token.instructions.createMint({...}).sendTransaction() for the token plugin's built-in instruction plans.

Switching networks

A kit client is bound to one chain and RPC endpoint. The cluster dropdown rebuilds the client in a useMemo keyed on the cluster and hands the new instance to ClientProvider, which reprovisions the subtree. See app/lib/client-provider.tsx.

Testing

npm run test

The tests in tests/ drive the real UI — click Connect Wallet, pick a wallet, fill in the transfer form, press Send SOL — and assert on-chain state before and after each click. Three pieces make that work without a browser or a wallet extension:

  • @solana/surfpool embeds a Surfpool Solana runtime in-process. Each test file boots its own surfnet on dynamic ports in well under a second, with cheatcodes to fund accounts (surfnet.fundSol), set token balances, deploy programs, and time travel. It's a native addon with prebuilt binaries for macOS (x64/arm64) and Linux x64.
  • A mock wallet-standard wallet (tests/mock-wallet.ts) registers itself like any browser extension would, so the app's real wallet discovery, connect flow, and transaction signing run unmodified — signatures come from an in-memory keypair.
  • Vitest + Testing Library render the actual app components in jsdom and interact with them by role and label, the same way a user would.

The tests point the app's client factory at the surfnet via the optional URL override on createAppClient — everything else (plugins, signing, subscriptions, live balance updates) is the production code path.

© 2026 Solana Foundation. All rights reserved.