litesvm, mollusk & solana-bankrun
Fast Solana program testing avoids full solana-test-validator round-trips. LiteSVM 0.6.x runs an in-process SVM for Rust tests. Mollusk executes single instructions against program ELF with fixtures. solana-bankrun (Bankrun) embeds a validator-like environment for TypeScript integration tests. Pick based on language and fidelity needs on Agave 4.1.1 semantics.
Recipe
Quick-reference recipe card - copy-paste ready.
[dev-dependencies]
litesvm = "0.6"
mollusk-svm = "0.1"npm install -D solana-bankrun @solana/kit@7.0.0use litesvm::LiteSVM;
let mut svm = LiteSVM::new();
// svm.add_program(...) and send txs in testsWhen to reach for this:
- Unit tests for Anchor/native programs in CI without Docker validators.
- Benchmarking CU usage across instruction variants.
- TS integration tests that load your
.soand assert account deltas. - Rapid red/green loops during security fixes.
Working Example
use litesvm::LiteSVM;
use solana_sdk::{
instruction::{AccountMeta, Instruction},
pubkey::Pubkey,
signature::{Keypair, Signer},
system_program,
transaction::Transaction,
};
#[test]
fn transfer_in_litesvm() {
let mut svm = LiteSVM::new();
let payer = Keypair::new();
let recipient = Keypair::new();
svm.airdrop(&payer.pubkey(), 1_000_000_000).unwrap();
let ix = Instruction {
program_id: system_program::ID,
accounts: vec![
AccountMeta::new(payer.pubkey(), true),
AccountMeta::new(recipient.pubkey(), false),
],
data: solana_sdk::system_instruction::transfer(&payer.pubkey(), &recipient.pubkey(), 10_000).data,
};
let bh = svm.latest_blockhash();
let tx = Transaction::new_signed_with_payer(&[ix], Some(&payer.pubkey()), &[&payer], bh);
svm.send_transaction(tx).unwrap();
let bal = svm.get_balance(&recipient.pubkey()).unwrap();
assert_eq!(bal, 10_000);
}What this demonstrates:
- LiteSVM airdrops lamports without CLI faucet.
- Real system program instruction executes in-process.
- Blockhash comes from svm state, not external RPC.
- Assertions read balances directly from svm.
Deep Dive
How It Works
- LiteSVM embeds Agave-compatible execution for loaded program binaries.
- Mollusk focuses on single-instruction harness with mocked accounts list.
- Bankrun spins bank state for TS tests with program deploy hooks.
- None replace full validator tests for RPC/network edge cases entirely.
Rust Crate Table
| Crate | Language | Fidelity | Speed |
|---|---|---|---|
litesvm | Rust | Multi-instruction txs | Very fast |
mollusk-svm | Rust | Single instruction | Fastest micro-benchmarks |
solana-program-test | Rust | Older async validator | Slower |
surfpool CLI | Any (RPC) | Mainnet fork sim | Medium |
TypeScript / NPM Table
| Package | Role | Pin |
|---|---|---|
solana-bankrun | Embedded bank for TS tests | Match Agave era |
@solana/kit | Build/send in tests | 7.0.0 |
anchor test runner | Legacy Anchor TS tests | 0.32.1 |
Rust Notes
// Load your program .so in LiteSVM tests
// svm.add_program(program_id, "target/deploy/my_program.so");
// Compare CU logs with `mollusk` for hot instruction tuningGotchas
- Testing without deployed BPF artifact - empty program id failures. Fix:
anchor buildbefore tests; wire path in CI. - Feature drift from mainnet - syscall availability differs by version. Fix: pin LiteSVM 0.6.x with Agave 4.1.1 toolchain.
- Bankrun program path wrong in monorepos - stale
.so. Fix: copy artifact in test setup script. - Over-mocking accounts in Mollusk - passes tests, fails mainnet. Fix: add LiteSVM integration cases.
- Skipping validator tests entirely - miss RPC serialization bugs. Fix: keep a thin
solana-test-validatorsuite.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
solana-test-validator | RPC-accurate integration | Sub-second unit loops |
| Surfpool 0.12.0 fork | Mainnet account state | Pure unit math |
| Devnet deploy tests | Pre-release smoke | Every PR commit |
| Formal verification | Critical invariants | All business logic |
FAQs
LiteSVM vs program-test?
LiteSVM is faster and simpler for most Anchor/native unit tests.
Mollusk when?
Micro-benchmarks and instruction-focused security cases.
Bankrun with kit?
Yes - build transactions with kit, execute in Bankrun context.
Anchor test harness?
anchor test can orchestrate validator; add LiteSVM for speed layers.
CU measurement?
Read consumption from logs in LiteSVM/Mollusk outputs.
CI caching?
Cache target/deploy/*.so artifacts between jobs.
Token program tests?
Load SPL programs into svm or use preloaded images per harness docs.
Flaky Bankrun?
Pin Node version and program deploy order; avoid race in parallel tests.
Fuzz + Mollusk?
Combine cargo-fuzz inputs with Mollusk execution for security research.
Surfpool complement?
Use Surfpool for forked state; LiteSVM for deterministic unit cases.
Related
- LiteSVM - detailed guide
- Mollusk - instruction harness
- Bankrun (TS) - TS tests
- Testing Basics - pyramid
Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0, and LiteSVM 0.6.x.