Bankrun (TS)
Bankrun provides fast in-process Solana VM tests from TypeScript without running solana-test-validator. Use it when your team lives in Anchor TS tests but needs LiteSVM-like speed.
Recipe
Quick-reference recipe card - copy-paste ready.
import { startAnchor, BankrunProvider } from "anchor-bankrun";
import { Program } from "@coral-xyz/anchor";
const context = await startAnchor("", [], []);
const provider = new BankrunProvider(context);
const program = new Program(idl, provider);When to reach for this:
- Anchor TS tests too slow on validator spin-up.
- Testing multiple instructions in one TypeScript file quickly.
- Teams preferring Mocha/
chaiover Rust#[test]. - CI pipelines avoiding flaky validator ports.
Working Example
import { startAnchor, BankrunProvider } from "anchor-bankrun";
import { Program, BN } from "@coral-xyz/anchor";
import { Keypair, PublicKey } from "@solana/web3.js";
import { describe, it } from "node:test";
import assert from "node:assert/strict";
describe("vault bankrun", async () => {
const context = await startAnchor(".", [], []);
const provider = new BankrunProvider(context);
const program = new Program(idl as any, provider);
it("deposits tokens", async () => {
const user = Keypair.generate();
context.setAccount(user.publicKey, {
lamports: 1_000_000_000,
data: Buffer.alloc(0),
owner: PublicKey.default,
executable: false,
});
const [vaultPda] = PublicKey.findProgramAddressSync(
[Buffer.from("vault"), user.publicKey.toBuffer()],
program.programId
);
await program.methods
.deposit(new BN(500_000))
.accounts({ user: user.publicKey, vault: vaultPda })
.signers([user])
.rpc();
const vault = await program.account.vault.fetch(vaultPda);
assert.equal(vault.balance.toNumber(), 500_000);
});
});What this demonstrates:
startAnchorloads workspace programs into in-process VM.BankrunProviderwires Anchor client without localhost RPC.context.setAccountseeds account state before instructions.
Deep Dive
How It Works
- Bankrun embeds SVM similar to LiteSVM but exposes Node-friendly API.
- Anchor program IDs and
.soartifacts load from workspace paths. - Transactions submit through provider like normal Anchor tests.
- No port 8899 - eliminates validator race conditions in CI.
Bankrun vs anchor test
| Aspect | Bankrun | anchor test (validator) |
|---|---|---|
| Startup | ~ms | seconds |
| RPC fidelity | High for programs | Full |
| SPL Token | Supported | Native |
| DeFi fork | Limited | Surfpool / clone |
TypeScript Notes
// Warp clock for time-dependent ix
context.warpToSlot(100n);Gotchas
- IDL out of sync - Stale IDL causes account resolution errors. Fix:
anchor buildbefore tests. - Missing SPL programs - Token CPIs need explicit program accounts in workspace config. Fix: Include
spl_token.soinstartAnchorprogram list. - Account rent - Underfunded accounts fail silently. Fix: Set lamports above rent-exempt minimum in
setAccount. - Not mainnet state - No fork by default. Fix: Use Surfpool for DeFi integration layer.
- Version drift - Bankrun must match Solana SDK used by Anchor 0.32.1. Fix: Pin versions in
package.json. - signers in rpc() - Forgetting
.signers([user])on mutating ix. Fix: Mirror validator test patterns.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| LiteSVM (Rust) | Rust-first team | TS-only developers |
| anchor test | Full RPC needed | Speed critical inner loop |
| Surfpool | Mainnet fork DeFi | Simple program logic |
FAQs
Does Bankrun replace anchor test entirely?
No - keep validator E2E for RPC-specific paths; Bankrun covers bulk of Anchor logic tests.
Anchor 0.32.1 compatible?
Use anchor-bankrun version aligned with your Anchor release - check package README.
Can I test versioned transactions?
Support evolves - verify ALT/versioned tx for your bankrun version; fall back to validator if unsupported.
How do I debug logs?
Enable verbose provider logs or catch transaction errors and print simulation logs field.
CI without validator service?
Yes - npm test with bankrun only; faster and no port conflicts.
Multiple programs?
Pass program paths array to startAnchor for CPI dependencies.
PDA tests?
Same as validator tests - findProgramAddressSync + program.methods...accounts.
Negative tests?
assert.rejects on rpc() expecting Anchor error codes.
Works with @solana/kit?
Bankrun uses web3.js provider model - kit tests can target bankrun RPC if exposed; Anchor path uses web3.js.
When to use Surfpool instead?
When instruction needs real mainnet pool/oracle accounts not easily mocked.
Related
- Anchor TS Tests - validator-based Anchor tests
- LiteSVM - Rust equivalent
- Testing Basics - pyramid
- Testing Best Practices - CI policy
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.