TLDR:Documentation Index
Fetch the complete documentation index at: https://chainstack-mintlify-flesh-empty-pages.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
- LiteSVM boots a Solana virtual machine inside your test process. No validator, no RPC, no gossip — just an in-memory bank you drive directly from Rust, TypeScript, or Python.
- It is 10–100× faster than
solana-test-validatorfor unit tests, and the author ofsolana-bankrunhas explicitly deprecated bankrun in favor of it. - Anchor v1.0.0 (Apr 2026) ships LiteSVM as the default test backend from
anchor init. The Solana Foundation’s dev-skill document lists LiteSVM alongside Mollusk as the unit-testing default. - This guide walks through the canonical testing stack (LiteSVM → Mollusk → Surfpool), loading and invoking your own program from Rust and TypeScript, Anchor integration via
anchor-litesvm, SPL token helpers, clock and feature-gate manipulation, and the pitfalls that will trip up anyone coming fromsolana-program-testor bankrun. - All code is verified against LiteSVM/litesvm v0.11.0, the litesvm npm package v1.0.0, brimigs/anchor-litesvm v0.4.0, and kevinheavey/solders v0.27.1 as of April 2026.
Why LiteSVM
Running every test againstsolana-test-validator is slow. Each suite spins up a full validator, waits for genesis, loads every built-in program, and then runs your transactions through the real consensus pipeline. For an iterative red-green-refactor loop, that overhead destroys flow.
LiteSVM is the opposite: it constructs a minimal in-process Bank containing only the programs and accounts you need, exposes it through an ergonomic LiteSVM struct, and lets you send transactions and inspect state with no RPC round-trip. A typical unit test takes tens of milliseconds instead of tens of seconds.
The tradeoff is that LiteSVM is not a validator. It does not replicate, it does not gossip, it does not model leader rotation, and its simulation of edge cases like compute-unit pricing, blockhash expiry, or sysvar rollover is opt-in. For end-to-end integration tests you still want Surfpool or a real devnet fork. For unit tests — especially the tight loop where you are writing business logic and want fast feedback — LiteSVM is the current best practice.
Where LiteSVM fits
Solana’s modern testing stack is a pyramid. Each tier trades fidelity for speed and serves a different purpose.| Tier | Tool | Runs | Best for |
|---|---|---|---|
| Unit, single-instruction | Mollusk | In-process, single program, no bank state | Pure instruction logic, CU benchmarking, fixture-based regression |
| Unit, multi-instruction | LiteSVM | In-process, full bank, sysvars, CPIs | End-to-end program flows, Anchor tests, token workflows |
| Integration | Surfpool | Local SVM with optional mainnet state fork | Cross-program state, realistic account layouts, RPC behavior |
| End-to-end | Devnet / mainnet | Real network | Final validation before release |
Under the hood, Surfpool uses LiteSVM as its execution engine. Understanding LiteSVM gives you the mental model for both.
What LiteSVM replaces
| Incumbent | How LiteSVM compares |
|---|---|
solana-test-validator | 10–100× faster, no process boundary, no port management. Use the validator when you need a real RPC server or cross-process integration. |
solana-program-test | Same authors; LiteSVM is the modern successor for new projects. Supports all loaders including upgradeable v3/v4; faster; ergonomic API. solana-program-test is still maintained by Anza and works fine for existing test suites. |
solana-bankrun | Deprecated by its own author in favor of the litesvm npm package. |
Install
Dependencies and pinning
LiteSVM does not re-export thesolana-* crates its API uses, so your Cargo.toml needs each one explicitly. Modern Solana has also dropped the monolithic solana-sdk in favor of fine-grained crates — the ones you actually need for a LiteSVM test are:
= or a Cargo.lock committed to your repo.
Version drift between these crates is the most common source of compile errors — people keep asking variations of the same question on Solana Stack Exchange. If you hit no method named resize on AccountInfo or VersionedTransaction: From<Transaction> not satisfied, the fix is almost always:
First test: transfer SOL
The minimal test that exercises the full loop — airdrop, build a transaction, send it, read accounts back. No program of your own yet.LiteSVM::new() already ships the System Program, SPL Token, and a handful of other core programs loaded, sysvars initialized, and the fee-payer airdrop pubkey funded. Everything else you add explicitly.
Load and invoke your own program
Compile the program once, then point LiteSVM at the.so. Every test starts from a fresh VM — no cross-test contamination.
1. Build the program
Even after Anchor 1.0 removed the Solana CLI requirement for
anchor test, you still need the Agave toolchain (cargo-build-sbf or cargo-build-bpf) to compile programs. LiteSVM loads .so bytes — it does not compile them.2. Load and invoke
add_program_from_file loads a BPF loader v2 program by default. If you need the upgradeable loader (loader v3) or loader v4, use add_program_with_loader.
Set accounts directly
You can prepopulate any account without running a transaction. This is the single most useful test primitive LiteSVM offers oversolana-test-validator.
Cloning real accounts from mainnet
When you need an actual token mint, program state, or any other on-chain account, there are two practical paths. Option 1 — Dump the raw account with the Solana CLI:.bin file is the raw account data. Pack it into solana_account::Account and hand it to svm.set_account. You still need to supply lamports and owner — fetch those with solana account <ADDR> --output json-compact in the same call.
Option 2 — Fetch at test time via Chainstack RPC:
Use an async RpcClient::get_account in your test harness to pull the live state, then set_account it into the SVM. This is how Surfpool’s mainnet-fork mode operates under the hood. If you find yourself doing this often, prefer Surfpool — it is purpose-built for mainnet-backed testing.
Either way, do not fake mint data with data: vec![5] or similar placeholder bytes. Anchor will reject the account with AccountNotInitialized (3012). Copy real bytes, or construct a proper spl_token::state::Mint and serialize it with Pack::pack.
Time travel: clock and slots
Testing time-dependent logic is the reason most teams move offsolana-test-validator. LiteSVM exposes the clock sysvar directly.
warp_to_slot and set_sysvar::<Clock>. Python uses svm.warp_to_slot(1000) and svm.set_sysvar(clock).
SPL tokens
The@solana/spl-token JavaScript helpers expect a real RPC and do not work against LiteSVM. The LiteSVM team publishes litesvm-token for Rust, which wraps the mint/account setup boilerplate.
spl-token instructions manually and send them via svm.sendTransaction. See LiteSVM’s SPL token docs for the complete pattern.
Anchor integration
Anchor v1.0.0 (released 2026-04-02) made LiteSVM the default unit-test backend foranchor init. For idiomatic Anchor tests you have two options.
Option 1: raw litesvm + anchor-lang::declare_program!
Hand-assemble instructions against an Anchor IDL. Verbose but dependency-free beyond LiteSVM itself.
Option 2: anchor-litesvm (recommended for most Anchor projects)
anchor-litesvm wraps LiteSVM with Anchor-aware sugar: discriminator derivation, account-struct binding, event parsing, token helpers. The maintainer claims ~78% less boilerplate than raw LiteSVM for typical Anchor flows.
anchor-litesvm is maintained by a single author and has a short release history (v0.4.0, published 2026-04-09). The API is stable against Anchor 1.0 + LiteSVM 0.11, but for long-running production test suites pin exact versions and watch the upstream for compatibility bumps.Compute budget and CU benchmarking
Two ways to tighten the compute budget in a LiteSVM test. Per-transaction (same API as production — prefer this):send_transaction returns a FailedTransactionMetadata with the CU overrun in its logs. Pair this with snapshot-style assertions in CI to alert on CU growth the moment a change lands.
For pure single-instruction CU benchmarking, reach for Mollusk instead — it is purpose-built for that one job.
Feature gates
LiteSVM 0.11 exposes the full AgaveFeatureSet. Use it to test behavior against future runtime semantics before the feature gate activates on mainnet.
Custom syscalls
LiteSVM 0.11 lets you register your own syscalls. This is niche but invaluable when testing programs that link against syscalls you want to stub or intercept.tests/custom_syscall.rs in the LiteSVM repo for the signature and a worked example.
Pitfalls
Most of these come straight from the LiteSVM issue tracker and community channels — they trip up almost everyone coming fromsolana-test-validator.
Agave 3.1 lock
LiteSVM 0.11 pinsagave-feature-set = 3.1.0 and all solana-* crates to 3.x. A project that still depends on solana-sdk 1.x or 2.x will hit transitive-version conflicts the moment you add LiteSVM. Upgrade the whole dependency tree to Solana 3.x first, or stay on an older LiteSVM — 0.7.1 is the last release before the Solana 3.0 bump (0.8.0 #223).
@solana/spl-token does not work
The high-level helpers (createMint, createAssociatedTokenAccount, …) in @solana/spl-token assume a real RPC. They will not work against LiteSVM. Build the SPL-token instructions by hand and send them via svm.sendTransaction, or use the Rust litesvm-token crate.
BPF upgradeable loader auto-load
Programs deployed via the upgradeable loader (BPF v3) are not always re-registered for subsequent transactions — see issue #240 and issue #263. Until this is resolved, preferadd_program_from_file (loader v2) for tests unless you specifically need loader v3/v4 semantics.
Python bindings lag Rust and JS
solders 0.27.1 — the PyPI package that ships the Python LiteSVM bindings — was released 2025-11-15. The Rust crate has since shipped feature-gate accounts, custom syscalls, and p-token binary loading in 0.10 and 0.11. Python callers do not have those features yet. For Python-primary projects, pin solders explicitly and budget for a version lag.
No standalone litesvm on PyPI
There is no separate litesvm Python package. You install solders and import from solders.litesvm import LiteSVM. The Python docs live at kevinheavey.github.io/solders/tutorials/litesvm.html.
DeclaredProgramIdMismatch (4100) in Anchor tests
Anchor programs bake their ID into declare_id!. When you load the .so into LiteSVM you must pass the same ID — not the program’s on-chain deploy ID, not a freshly generated one. Running anchor keys sync updates declare_id! in source but does not touch the keypair LiteSVM loads. Easiest fix: read the keypair your build produced.
Anchor discriminator when decoding accounts
svm.get_account(&pda).data gives you the raw account buffer including Anchor’s 8-byte discriminator. Skip those bytes before borsh-deserializing, or use Account::try_deserialize which handles it for you.
&data[..] (without the 8-byte skip) is the most common cause of InstructionDidNotDeserialize.
Error visibility
By default, a failed transaction gives youFailedTransactionMetadata but no logs. Pull them explicitly.
svm.getTransaction(signature) returns null by default in LiteSVM — transaction history storage is opt-in via .with_transaction_history(capacity).
Precompile syscalls require a feature flag
Tests that exercisesecp256k1, secp256r1, or ed25519 precompiles need both the precompiles crate feature and the agave-precompiles dev-dep. Without them the precompile verifier silently fails.
gRPC vs RPC simulation divergence
Issue #317, filed 2026-04-03 and still open, reports divergence in simulation output between gRPC and RPC paths. If you rely on simulation results for pre-flight logic, cross-check against a real validator before shipping to production.No Windows binaries
Issue #215 has been open since September 2025. Docker or WSL2 is the only path on Windows. Teams with mixed-OS developer machines should set this expectation up front.When not to use LiteSVM
Reach for a different tool if any of these apply:- You need to test network effects, leader rotation, or gossip behavior. Use a real local cluster.
- You need mainnet state or cross-program interactions with deployed programs you do not control. Use Surfpool with its mainnet-fork mode.
- You are running a Windows-only build environment and cannot use Docker. Stick with
solana-test-validatoruntil LiteSVM ships Windows binaries. - You want CU-accurate benchmarking of a single instruction. Use Mollusk — LiteSVM’s compute budget is good enough for regression detection but Mollusk is purpose-built for the measurement itself.
See also
- Solana: Anchor development — where Anchor 1.0 makes LiteSVM the default test backend.
- Solana: Program derived addresses and cross-program invocations — the account-layout knowledge you need to write meaningful LiteSVM tests.
- Solana: Escrow pattern — a full DeFi primitive you can unit-test in LiteSVM in under 100 ms.
- LiteSVM reference docs (Rust).
- LiteSVM TypeScript docs.
- solders LiteSVM tutorial (Python).
- anchor-litesvm on crates.io.
- Mollusk — Anza’s single-instruction harness.
- Surfpool — integration-tier SVM with mainnet-fork support.
Reference repos
These are the source repositories we worked against while writing this guide. They stay closer to reality than docs — check them first when something here looks off.- LiteSVM/litesvm — test-harness source; API surface, error paths, and feature-gate behavior verified against this
- brimigs/anchor-litesvm — Anchor ↔ LiteSVM bridge used in the Rust examples
- anza-xyz/mollusk — alternative lightweight runtime evaluated and cited for contrast
- kevinheavey/solders — Python bindings used by the LiteSVM Python harness
- kevinheavey/solana-bankrun — predecessor test runtime; useful for understanding migration paths