The Solana Web3.js SDK is a powerful JavaScript library for building decentralized applications on the Solana blockchain, supporting development across Node.js, web browsers, and React Native environments. On November 7, 2024, Anza Labs unveiled Web3.js 2.0 — a major upgrade packed with modern features, performance enhancements, and developer-friendly improvements. This guide will walk you through what’s new in the SDK, how to migrate effectively, and how to send optimized transactions using best practices.
Whether you're building dApps, wallets, or on-chain programs, understanding this updated SDK is essential for maximizing efficiency and reliability in your Solana development workflow.
What's New in Web3.js 2.0?
The release of Web3.js 2.0 brings significant improvements that empower developers with better tools and faster execution. Here are the key upgrades:
Faster Cryptographic Operations
Web3.js 2.0 leverages native Ed25519 cryptographic APIs available in modern JavaScript runtimes like Node.js and Safari 17. This results in up to 10x faster key pair generation, transaction signing, and message verification — a game-changer for high-throughput applications.
Tree-Shakable and Lightweight Bundle
One of the most impactful changes is full tree-shaking support. Developers can now import only the modules they use, drastically reducing bundle sizes in production builds. Additionally, the new SDK has zero external dependencies, making it more secure and easier to audit.
Enhanced Flexibility and Customization
Developers gain greater control over their tooling with support for:
- Custom RPC instances with tailored methods
- Pluggable network transports and custom transaction signers
- Extensible primitives for network handling, confirmation logic, and encoding/decoding
Moreover, TypeScript clients for on-chain programs are now hosted under the @solana-program GitHub organization. These are auto-generated using Codama IDL, enabling rapid client generation for custom Solana programs.
👉 Discover how modern SDKs streamline blockchain development
How to Send a Transaction Using Web3.js 2.0
Let’s build a simple program that transfers lamports (Solana’s smallest unit) from one wallet to another. We’ll follow best practices to ensure high success rates and fast confirmations — even during network congestion.
Prerequisites
Before we begin:
- Install Node.js
- Use a compatible IDE such as VS Code
Step 1: Initialize Your Project
Start by setting up a new Node.js project:
npm init -y
mkdir src
touch src/index.jsInstall the required dependencies:
npm install @solana/web3.js@2
npm install @solana-program/system
npm install @solana-program/compute-budgetThese packages provide:
@solana/web3.js: Core functionality for interacting with Solana@solana-program/system: Access to system-level instructions like transfers@solana-program/compute-budget: Tools for setting priority fees and compute limits
Step 2: Define Source and Destination Addresses
In src/index.js, define your source (signer) and destination addresses:
import { address, createKeyPairSignerFromBytes, getBase58Encoder } from '@solana/web3.js';
async function main() {
const destinationAddress = address('public-key-to-send-lamports-to');
const secretKey = "add-your-private-key"; // Replace with actual private key
const sourceKeypair = await createKeyPairSignerFromBytes(
getBase58Encoder().encode(secretKey)
);
}
main();Security Note: Never hardcode private keys in production code. Use environment variables or secure key management systems.
Step 3: Configure RPC Connection
Set up connections to a Solana RPC endpoint using HTTP and WebSocket:
import {
createSolanaRpc,
createSolanaRpcSubscriptions,
sendAndConfirmTransactionFactory
} from '@solana/web3.js';
const rpcUrl = "https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY";
const wssUrl = "wss://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY";
const rpc = createSolanaRpc(rpcUrl);
const rpcSubscriptions = createSolanaRpcSubscriptions(wssUrl);
const sendAndConfirmTransaction = sendAndConfirmTransactionFactory({
rpc,
rpcSubscriptions
});You can obtain these URLs from platforms like Helius or QuickNode.
Step 4: Create the Transfer Instruction
Use the system program’s built-in transfer instruction:
import { getTransferSolInstruction, lamports } from '@solana-program/system';
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
const instruction = getTransferSolInstruction({
amount: lamports(1),
destination: destinationAddress,
source: sourceKeypair
});Step 5: Build the Transaction Message
All messages in v2.0 are version-aware. Use functional composition via pipe() to construct the message:
import {
pipe,
createTransactionMessage,
setTransactionMessageFeePayer,
setTransactionMessageLifetimeUsingBlockhash,
appendTransactionMessageInstruction
} from '@solana/web3.js';
const transactionMessage = pipe(
createTransactionMessage({ version: 0 }),
tx => setTransactionMessageFeePayer(sourceKeypair.address, tx),
tx => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
tx => appendTransactionMessageInstruction(instruction, tx)
);This approach ensures clean, readable code while progressively building the transaction.
Step 6: Sign and Optimize the Transaction
Sign the message and estimate priority fee using Helius API:
import { signTransactionMessageWithSigners, getBase64EncodedWireTransaction } from '@solana/web3.js';
const signedTx = await signTransactionMessageWithSigners(transactionMessage);
// Get priority fee estimate
const encodedTx = getBase64EncodedWireTransaction(signedTx);
const response = await fetch(rpcUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
jsonrpc: '2.0',
id: 'priority-fee',
method: 'getPriorityFeeEstimate',
params: [{
transaction: encodedTx,
options: { transactionEncoding: 'base64', recommended: true }
}]
})
});
const { result } = await response.json();
const priorityFee = result.priorityFeeEstimate;Estimate compute units with a safety buffer:
import { getComputeUnitEstimateForTransactionMessageFactory } from '@solana/web3.js';
const getEstimate = getComputeUnitEstimateForTransactionMessageFactory({ rpc });
let computeUnits = await getEstimate(transactionMessage);
computeUnits = Math.max(1000, Math.ceil(computeUnits * 1.1));Rebuild the transaction with compute budget instructions:
import { getSetComputeUnitLimitInstruction, getSetComputeUnitPriceInstruction } from '@solana-program/compute-budget';
const { value: finalBlockhash } = await rpc.getLatestBlockhash().send();
const finalMessage = pipe(
transactionMessage,
tx => setTransactionMessageLifetimeUsingBlockhash(finalBlockhash, tx),
tx => appendTransactionMessageInstructions([
getSetComputeUnitPriceInstruction({ microLamports: priorityFee }),
getSetComputeUnitLimitInstruction({ units: computeUnits })
], tx)
);
const finalSignedTx = await signTransactionMessageWithSigners(finalMessage);Step 7: Send and Confirm
Finally, send the transaction with optimal settings:
await sendAndConfirmTransaction(finalSignedTx, {
commitment: 'confirmed',
maxRetries: 0,
skipPreflight: true
});Setting skipPreflight: true speeds up execution but should only be used when you're confident in your transaction structure.
👉 Learn how top developers optimize Solana transactions
Frequently Asked Questions (FAQ)
Q: Is Web3.js 2.0 backward compatible with v1.x?
A: No, Web3.js 2.0 introduces breaking changes. You’ll need to update imports and adapt to the new modular architecture.
Q: Why should I use tree-shaking in my dApp?
A: Tree-shaking reduces bundle size by including only the code you actually use, leading to faster load times and improved UX — especially important for web-based wallets and interfaces.
Q: How do I avoid transaction failures due to expired blockhashes?
A: Always fetch a fresh blockhash just before sending the final transaction. Blockhashes expire after ~2 minutes.
Q: Can I use Web3.js 2.0 in React or frontend frameworks?
A: Yes! It works seamlessly in browser environments. Just ensure you’re not exposing private keys client-side.
Q: What are microLamports in priority fees?
A: A microLamport is one millionth of a lamport. Priority fees are priced per compute unit, allowing granular control over transaction cost and speed.
Q: Where can I find auto-generated clients for my Solana program?
A: Visit the @solana-program GitHub organization — clients are generated using Codama IDL from your program’s interface definition.
👉 Explore advanced blockchain development tools today
Conclusion
The Solana Web3.js 2.0 SDK marks a major leap forward in blockchain development tooling. With native crypto support, modular design, tree-shakability, and auto-generated TypeScript clients, it empowers developers to build faster, leaner, and more reliable applications on Solana.
By following best practices — such as optimizing compute units, setting accurate priority fees, and managing blockhash lifetimes — you can significantly improve transaction success rates and user experience.
As the ecosystem evolves, staying updated with SDK changes ensures your projects remain performant and secure.
Core Keywords: Solana Web3.js SDK, Web3.js 2.0, Solana transactions, blockchain development, tree-shaking JavaScript, priority fees Solana, compute units optimization