14 KiB
title, description
| title | description |
|---|---|
| @solana/kit Quick Start | Quick-start guide for @solana/kit using createClient + .use() plugin composition for RPC, signers, transaction sending, account fetching, and common Solana patterns. |
@solana/kit Reference
@solana/kit is the JavaScript SDK for building Solana applications. Modular, tree-shakable, full TypeScript support. Clients are built by composing plugins onto createClient() via .use().
Contents
- Installation
- Quick Start
- Client API
- Core Concepts
- Common Patterns
- Codama Program Clients
- Package Overview
- Best Practices
- Reference Files
Installation
npm install @solana/kit @solana/kit-plugin-rpc @solana/kit-plugin-signer
# or: pnpm add @solana/kit @solana/kit-plugin-rpc @solana/kit-plugin-signer
For LiteSVM testing add @solana/kit-plugin-litesvm. For browser wallet connection add @solana/kit-plugin-wallet. For Codama-generated program clients add the relevant @solana-program/* package(s).
Minimum version: Solana Kit v7 (plugin packages 0.13+). @solana/kit-plugin-wallet needs 0.14+ specifically — its React hooks take the client as an explicit argument only from that version on.
Quick Start
Local Development
import { createClient } from '@solana/kit';
import { solanaLocalRpc } from '@solana/kit-plugin-rpc';
import { signerFromFile } from '@solana/kit-plugin-signer';
// `signerFromFile` sets BOTH payer and identity to the loaded keypair (the common case).
// Other options:
// - `signer(existingSigner)` // explicit signer you already hold
// - `generatedSigner()` + `airdropSigner(lamports(n))` // fresh local/devnet signer, funded after RPC is installed
// - `payer(...)` + `identity(...)` // when fees and authority come from different keypairs
const client = await createClient()
.use(signerFromFile('~/.config/solana/id.json'))
.use(solanaLocalRpc());
console.log('Payer:', client.payer.address);
await client.sendTransaction([myInstruction]);
Production (Mainnet/Devnet)
import { createClient } from '@solana/kit';
import { solanaDevnetRpc, solanaMainnetRpc } from '@solana/kit-plugin-rpc';
import { signer } from '@solana/kit-plugin-signer';
const client = createClient()
.use(signer(mySigner)) // sets payer + identity; use payer(...) + identity(...) if they differ
.use(solanaDevnetRpc()); // or solanaMainnetRpc({ rpcUrl: 'https://...' })
await client.sendTransaction([myInstruction]);
solanaDevnetRpc() defaults to https://api.devnet.solana.com and bundles airdrop. solanaMainnetRpc({ rpcUrl }) is type-narrowed to a mainnet URL — no devnet-only methods like airdrop.
Testing with LiteSVM
import { createClient, lamports } from '@solana/kit';
import { litesvm } from '@solana/kit-plugin-litesvm';
import { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';
const client = await createClient()
.use(generatedSigner())
.use(litesvm())
.use(airdropSigner(lamports(1_000_000_000n)));
client.svm.addProgramFromFile(myProgramAddress, 'program.so');
await client.sendTransaction([myInstruction]);
Full documentation: LiteSVM.
Client API
After applying solanaRpc / solanaLocalRpc / solanaDevnetRpc / solanaMainnetRpc (or litesvm), the client exposes:
| Property/Method | Description |
|---|---|
client.rpc |
RPC methods (getBalance, getAccountInfo, etc.) |
client.rpcSubscriptions |
WebSocket subscriptions (RPC plugins only) |
client.payer |
Transaction fee payer signer (set by signer() or payer()) |
client.identity |
Authority signer (set by signer() or identity()) |
client.sendTransaction(instructions) |
Plan + sign + send in one call |
client.sendTransactions(plan) |
Execute a planned multi-tx plan |
client.planTransaction(s) |
Plan without executing |
client.getMinimumBalance(dataSize) |
Rent-exempt minimum lamports |
client.airdrop(address, lamports) |
Faucet (devnet/local/litesvm only) |
client.svm |
LiteSVM instance (litesvm plugin only) |
solanaRpc({ ... }) accepts rpcUrl (required) plus rpcSubscriptionsUrl, transactionConfig (priority fees), maxConcurrency, skipPreflight, and the underlying rpcConfig / rpcSubscriptionsConfig. See plugins.md for the full options table, plugin catalog, and custom composition.
Core Concepts
Branded Types
import { address, lamports, signature } from '@solana/kit';
const myAddress = address('So11111111111111111111111111111111111111112');
const myLamports = lamports(1_000_000_000n);
const mySig = signature('5eykt...');
SOL ↔ Lamports
Sol is a fixed-point value ({ raw, decimals: 9, ... }), not a bigint — convert before passing it to an instruction:
import { lamports, lamportsToSol, sol, solToLamports, formatDecimalFixedPoint } from '@solana/kit';
solToLamports(sol('1.5')); // lamports(1_500_000_000n)
lamportsToSol(lamports(1_500_000_000n)); // Sol fixed-point representing 1.5
// Display
const formatter = new Intl.NumberFormat(undefined, { maximumFractionDigits: 5 });
formatDecimalFixedPoint(formatter, lamportsToSol(balance)); // "1.5"
sol() parses in 'strict' rounding mode by default and throws on more than 9 fractional digits; pass a RoundingMode (e.g. sol('1.1234567891', 'round')) to accept a rounded result. In TypeScript never hand-roll / 1e9 — floats lose precision on large balances.
Signers
import { generateKeyPairSigner } from '@solana/kit';
const signer = await generateKeyPairSigner();
// signer.address — the public key
// signer is a TransactionSigner
Codec Direction
encode(): values →Uint8Arraydecode():Uint8Array→ values
Always use native codecs (e.g., getBase58Codec()). Never import bs58.
See codecs.md for full codec patterns.
Common Patterns
Send SOL Transfer
import { createClient, address, lamports } from '@solana/kit';
import { solanaLocalRpc } from '@solana/kit-plugin-rpc';
import { signerFromFile } from '@solana/kit-plugin-signer';
import { getTransferSolInstruction } from '@solana-program/system';
const client = await createClient()
.use(signerFromFile('~/.config/solana/id.json'))
.use(solanaLocalRpc());
const ix = getTransferSolInstruction({
source: client.payer,
destination: address('recipient...'),
amount: lamports(1_000_000_000n),
});
await client.sendTransaction([ix]);
Fetch Account
import { fetchEncodedAccount, assertAccountExists, decodeAccount } from '@solana/kit';
const account = await fetchEncodedAccount(client.rpc, myAddress);
assertAccountExists(account);
const decoded = decodeAccount(account, myDecoder);
See accounts.md for batch fetching, PDAs, subscriptions, and token queries.
Token Operations
Use the tokenProgram() plugin from @solana-program/token for a fluent token API. It auto-derives ATAs, auto-creates them if needed, and defaults the payer from the client.
import { createClient, generateKeyPairSigner } from '@solana/kit';
import { solanaLocalRpc } from '@solana/kit-plugin-rpc';
import { signerFromFile } from '@solana/kit-plugin-signer';
import { tokenProgram } from '@solana-program/token';
const client = await createClient()
.use(signerFromFile('~/.config/solana/id.json'))
.use(solanaLocalRpc())
.use(tokenProgram());
const mintAuthority = await generateKeyPairSigner();
const mint = await generateKeyPairSigner();
// Create a new mint
await client.token.instructions
.createMint({ newMint: mint, decimals: 2, mintAuthority: mintAuthority.address })
.sendTransaction();
// Mint tokens to an owner's ATA (created automatically if needed)
await client.token.instructions
.mintToATA({
mint: mint.address,
owner: recipientAddress,
mintAuthority,
amount: 1_000_000n,
decimals: 2,
})
.sendTransaction();
// Transfer tokens to a recipient's ATA (auto-derives source + destination)
await client.token.instructions
.transferToATA({
mint: mint.address,
authority: ownerSigner,
recipient: recipientAddress,
amount: 500n,
decimals: 2,
})
.sendTransaction();
See programs/token.md for low-level instruction patterns and programs/token-2022.md for Token Extensions.
Custom Program Operations
Programs that ship a Kit plugin follow the same .use() pattern:
import { createClient } from '@solana/kit';
import { solanaDevnetRpc } from '@solana/kit-plugin-rpc';
import { signer } from '@solana/kit-plugin-signer';
import { myProgram } from '@my-programs/operations';
const client = createClient()
.use(signer(mySigner))
.use(solanaDevnetRpc())
.use(myProgram());
await client.myProgram.instructions
.handyInstruction({ /* args */ })
.sendTransaction();
RPC Queries
// Balance
const { value: balance } = await client.rpc.getBalance(myAddress).send();
// Token accounts
const { value: tokenAccs } = await client.rpc.getTokenAccountsByOwner(
owner,
{ mint: mintAddr },
{ encoding: 'jsonParsed' },
).send();
// Latest blockhash
const { value: blockhash } = await client.rpc.getLatestBlockhash().send();
Codama Program Clients
@solana-program/* packages are Codama-generated, Kit-compatible instruction builders:
| Package | Purpose |
|---|---|
@solana-program/system |
Account creation, transfers, nonces |
@solana-program/token |
SPL Token operations |
@solana-program/token-2022 |
Token Extensions (transfer fees, metadata, etc.) |
@solana-program/compute-budget |
CU limits & priority fees |
@solana-program/memo |
Memo program |
@solana-program/stake |
Staking operations |
Note: These packages export both low-level get{Name}Instruction() helpers and higher-level program plugins (e.g., tokenProgram()) that attach fluent APIs to the client. ATA functions are in @solana-program/token and @solana-program/token-2022, not a separate package.
See codama.md for naming conventions and patterns.
Package Overview
| Package | Purpose |
|---|---|
@solana/kit |
Main SDK, re-exports all sub-packages, exports createClient |
@solana/kit-plugin-rpc |
All-in-one RPC plugins: solanaRpc, solanaMainnetRpc, solanaDevnetRpc, solanaLocalRpc (plus low-level rpc, rpcAirdrop, rpcTransactionPlanner, rpcTransactionPlanExecutor) |
@solana/kit-plugin-signer |
Signer plugins. Default signer* variants set both payer and identity (signer, generatedSigner, signerFromFile). Use airdropSigner to fund an already-installed signer; use generatedSignerWithSol only when an airdrop function is already installed. Role-specific payer* and identity* variants for when the two roles differ. |
@solana/kit-plugin-wallet |
Browser wallet connection (Wallet Standard): walletSigner, walletPayer, walletIdentity, walletWithoutSigner; adds client.wallet (getState(), connect()); React hooks in @solana/kit-plugin-wallet/react |
@solana/kit-plugin-litesvm |
All-in-one litesvm plugin (Node.js only) for in-memory testing |
@solana/kit-plugin-instruction-plan |
planAndSendTransactions and instruction batching primitives |
@solana/addresses |
Address validation |
@solana/accounts |
Account fetching/decoding |
@solana/codecs |
Data encoding/decoding |
@solana/rpc |
JSON RPC client primitives |
@solana/rpc-subscriptions |
WebSocket subscription primitives |
@solana/transactions |
Compile/sign/serialize |
@solana/transaction-messages |
Build tx messages |
@solana/signers |
Signing abstraction |
@solana/keychain |
Common Signing Interface for external signers |
@solana/instruction-plans |
Multi-instruction batching |
@solana/errors |
Error identification/decoding |
@solana/functional |
Pipe and compose utilities |
@solana/react |
Kit-native React bindings (ClientProvider, useClient, data/subscription hooks, SWR & TanStack Query adapters). Its legacy Wallet Standard hooks are being deprecated — use @solana/kit-plugin-wallet/react |
@solana/compat |
Type conversions between Kit and legacy web3.js v1 values |
Deprecated packages — do not install: @solana/kit-plugins (umbrella), @solana/kit-plugin-airdrop (use rpcAirdrop/litesvmAirdrop), @solana/kit-plugin-payer (use @solana/kit-plugin-signer), @solana/kit-client-rpc / @solana/kit-client-litesvm (use the solanaRpc / litesvm all-in-one plugins).
Best Practices
- Compose with
.use()—createClient().use(signer(...)).use(solanaRpc(...)); the signer plugin must come before the RPC/litesvm plugin. Use the role-specificpayer()+identity()variants only when fees and authority come from different keypairs. - Use branded types —
address(),lamports(),signature(). - Use
@solana-program/*instruction builders over hand-rolled instruction data. - Handle account existence —
assertAccountExists()before decode. - Set compute budget — pass
transactionConfigtosolanaRpc({ ... })or use manual CU estimation for production. See programs/compute-budget.md.
Reference Files
- plugins.md — Plugin catalog, custom composition, ordering rules
- accounts.md — Fetching, decoding, batch, PDAs, subscriptions
- codecs.md — Complete codec patterns
- react.md — React hooks and wallet integration
- codama.md — Codama patterns, naming conventions, program clients
- gotchas.md — Common type errors & fixes
- advanced.md — Manual transaction building, direct RPC, building plugins, custom clients
- programs/ — Program client references (system, token, token-2022, compute-budget)