How to Build a Solana App with Solana Kit in 2026
Learn the current Solana Kit workflow by building a Devnet app that connects to Solana, creates a signer, reads the network, and sends a test transaction.
On this page
Solana development has shifted toward a newer JavaScript toolkit, and the change matters most when you build the first working transaction. Solana Kit is now the current SDK path for JavaScript applications, with version 7+ and plugin packages that separate RPC connections, signing, and transaction execution. This tutorial shows how to create a small Devnet application, connect it to Solana, inspect the network, and send a test transaction without relying on the older API style.
Why Solana Kit changes the development workflow
Solana Kit is the renamed 2.x line of the former web3.js project. Instead of putting most functionality behind one large client object, Kit lets you compose a client from smaller pieces called plugins. An RPC connection is the service your application uses to read from and submit data to Solana, while a signer is the component that authorizes transactions. This separation makes the same client pattern useful in scripts, server routes, and user interfaces.
The current Solana documentation recommends Kit version 7 or newer, while the related Kit plugin packages are on the 0.13 or newer line. Solana also shipped Kit v7.1.1 in its August 24 developer update, making the newer API worth learning instead of starting another project around the legacy web3.js interface.
What you need before writing code
You need Node.js, npm, and a basic understanding of JavaScript or TypeScript. We will use Solana Devnet, which is a separate network intended for development and testing rather than real-value transactions. Your test signer will be generated locally, so you should never copy a development secret key into a production application or commit it to a source repository.
The finished example will do three things in order: create a signer, connect that signer to Solana Devnet, and read the current slot. A slot is Solana's unit of block-production time, so printing one proves that your program can communicate with the network before you attempt a transaction.
Set up a fresh Solana project
Create an empty directory and initialize a Node.js project. Keeping this example small makes it easier to see which package performs each job.
mkdir solana-kit-demo
cd solana-kit-demo
npm init -y
npm install @solana/kit @solana/kit-plugin-rpc @solana/kit-plugin-signerThe three packages have deliberately different responsibilities. The main Kit package provides the client and cryptographic primitives, the RPC plugin connects the application to a Solana cluster, and the signer plugin gives the client an account that can authorize operations.
Create the Solana client before sending anything
Create a file named index.mjs and start by generating a signer and composing the client. The important detail is the order: the signer is registered before the Devnet RPC bundle because the RPC setup expects a payer to already exist.
import {
createClient,
generateKeyPairSigner
} from "@solana/kit";
import { solanaDevnetRpc } from "@solana/kit-plugin-rpc";
import { signer } from "@solana/kit-plugin-signer";
const payer = await generateKeyPairSigner();
const client = createClient()
.use(signer(payer))
.use(solanaDevnetRpc());
const slot = await client.rpc.getSlot().send();
console.log("Current slot:", slot);Run the program with node index.mjs. If the setup is correct, the terminal prints a current slot number. That number is the checkpoint you need before moving forward: it confirms that Node can load the packages, the signer was created, and the client reached Devnet through its RPC connection.
Fund the test account on Devnet
A signer can exist without having any SOL, but it cannot pay transaction fees until its account has funds. Devnet provides test SOL through an airdrop mechanism, and Kit's Devnet RPC setup exposes the required airdrop capability for development scripts.
For a small test application, add an airdrop before the transaction. The exact balance you request should remain modest because the purpose is only to exercise the application. Do not transfer real funds into a development key simply to make a tutorial work.
const { value: balanceBefore } =
await client.rpc.getBalance(payer.address).send();
console.log("Balance before:", balanceBefore);
await client.airdrop({
recipientAddress: payer.address,
lamports: 1_000_000_000n
});
const { value: balanceAfter } =
await client.rpc.getBalance(payer.address).send();
console.log("Balance after:", balanceAfter);One SOL contains one billion lamports, so the example requests 1 SOL worth of Devnet units. These are test tokens and have no mainnet value. If the airdrop is rate-limited, wait and try again rather than changing the application to use a real wallet.
Send your first Solana transaction
Now the application has a payer and a network connection, so you can construct an instruction. An instruction describes an operation for a Solana program to execute. In this example, the system program handles a simple SOL transfer, while Kit takes care of transaction planning, recent block information, signing, and submission.
import {
address,
createClient,
generateKeyPairSigner,
lamports
} from "@solana/kit";
import { getTransferSolInstruction }
from "@solana-program/system";
import { solanaDevnetRpc }
from "@solana/kit-plugin-rpc";
import { signer }
from "@solana/kit-plugin-signer";
const payer = await generateKeyPairSigner();
const client = createClient()
.use(signer(payer))
.use(solanaDevnetRpc());
const destination = address("REPLACE_WITH_A_DEVNET_ADDRESS");
const transfer = getTransferSolInstruction({
source: client.payer,
destination,
amount: lamports(10_000_000n)
});
const result = await client.sendTransaction([transfer]);
console.log("Submitted:", result.context.signature);The example transfers 10 million lamports, which is 0.01 SOL. The destination must be replaced with an address you control for testing. Do not paste an unfamiliar address from a random tutorial or social-media post into a transaction just because the code happens to compile.
Understand what sendTransaction is doing for you
The useful part of Kit is not just the shorter syntax. When you call sendTransaction, the client can resolve the recent block information, estimate compute requirements, sign with the configured payer, and submit the transaction. That removes several pieces of transaction plumbing that developers previously had to connect manually.
The returned result contains the transaction signature under result.context.signature. A signature is the identifier you can use to check whether the network accepted the transaction. If you are building a real application, keep the signature available for logging and user-facing status rather than treating submission as proof that the transaction has reached the final state you expect.
Do not use the generated signer as a production wallet
The generated signer is useful because it keeps the tutorial self-contained, but it is not the right pattern for a consumer application. A production app normally needs a wallet integration in which the user controls the signing operation, while a backend service should use a dedicated key-management approach rather than exposing raw private-key material in application code.
Kit also separates signer roles. A client can use a full signer, a payer that only covers transaction fees, or an identity that represents application authority. That distinction matters when you move from a toy script to a larger application because not every component should receive permission to sign every kind of transaction.
What changes when you move beyond Devnet
Changing from Devnet to mainnet is not simply a matter of swapping one line and sending real money. Mainnet has no development airdrop, and every transaction has real financial consequences. Replace the Devnet RPC configuration only after the transaction logic has been tested, validate destination addresses, introduce proper wallet or key-management controls, and add error handling around failed submissions.
Solana's recent protocol work also makes transaction design worth revisiting. The network is moving toward larger transaction sizes through the v1 transaction format, with the maximum size increasing from 1,232 bytes to 4,096 bytes, while existing legacy and v0 formats remain usable. The rollout is staged, and client support has been developing alongside it, so applications should not assume that every environment can immediately rely on v1 transactions.
Three mistakes that cause most beginner failures
The first mistake is mixing old web3.js examples with the Kit API. The concepts are related, but the APIs are different enough that copying individual imports or classes from an older tutorial can create confusing type and runtime errors. Start with Kit-native examples and add dependencies only when the current documentation requires them.
The second mistake is putting the RPC connection before the signer. The current Kit client pattern expects the payer to be available before the Devnet RPC bundle is attached. Keeping that order also makes the reason for the client composition easier to understand: first establish who can authorize the work, then attach the network capabilities that use that authority.
The third mistake is testing against mainnet too early. Devnet gives you a safer place to learn transaction construction, balances, signatures, and error handling. Once the program behaves correctly there, you can separately evaluate production wallet integration, key management, RPC reliability, transaction confirmation, and the network features your application actually needs.
Where this leaves a new Solana project
A useful Solana application now has a clearer starting point than simply copying a legacy web3.js snippet: compose a Kit client, give it only the signing authority it needs, attach the appropriate RPC environment, build instructions with program clients, and let the transaction planner handle the routine mechanics. That pattern scales from a command-line experiment to server-side code and, with the appropriate wallet integration, a user-facing application.
The next practical step is to replace the simple SOL transfer with the program your application actually needs. Before doing that, keep the Devnet version working as a reference implementation. When Solana protocol changes such as larger v1 transactions become relevant to your workload, you can then test those capabilities deliberately instead of changing several layers of the application at once.
Written by


