> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/solana-foundation/anchor/llms.txt
> Use this file to discover all available pages before exploring further.

# LiteSVM

> Fast and lightweight testing for Solana programs in Rust, TypeScript, and Python.

## Overview

[LiteSVM](https://github.com/LiteSVM/litesvm) is a fast and lightweight library for testing Solana programs. It works by creating an in-process Solana VM optimized for program developers, making it much faster to run and compile than alternatives like `solana-program-test` and `solana-test-validator`.

LiteSVM is available in:

* **Rust** - Full-featured testing in Rust
* **TypeScript/JavaScript** - Client-side testing with full SVM access
* **Python** - Testing via the [`solders`](https://pypi.org/project/solders/) library

## Key Features

* **Blazingly Fast** - No validator startup time, tests run in milliseconds
* **Lightweight** - Minimal resource usage, compiles quickly
* **Multi-Language** - Use Rust, TypeScript, or Python
* **Time Travel** - Manipulate clock and slots for testing time-dependent logic
* **Arbitrary Accounts** - Write any account data, even impossible states
* **Real SVM** - Tests run against actual Solana VM, not a mock

## When to Use LiteSVM

LiteSVM is ideal for:

* **Unit Testing** - Test individual instructions in isolation
* **Fast Iteration** - Rapid test feedback during development
* **CI/CD Pipelines** - Quick test execution in automated builds
* **Account Manipulation** - Testing edge cases with custom account states
* **Time-Dependent Logic** - Programs that use the Clock sysvar

Use `solana-test-validator` when you need full RPC support or want to test against real validator behavior.

## Installation

<Tabs items={["Rust", "TypeScript", "Python"]}>
  ```bash tab="Rust" theme={null}
  cargo add litesvm --dev
  ```

  ```bash tab="TypeScript" theme={null}
  npm install litesvm --save-dev
  ```

  ```bash tab="Python" theme={null}
  # LiteSVM is part of solders
  pip install solders
  ```
</Tabs>

## Quick Start

Here's a simple transfer example to get you started:

<Tabs items={["Rust", "TypeScript", "Python"]}>
  ```rust tab="Rust" theme={null}
  use litesvm::LiteSVM;
  use solana_sdk::{
      signature::{Keypair, Signer},
      transaction::Transaction,
      system_instruction::transfer,
      message::Message,
  };

  #[test]
  fn test_transfer() {
      let mut svm = LiteSVM::new();
      let from = Keypair::new();
      let to = Keypair::new();
      
      // Airdrop SOL to sender
      svm.airdrop(&from.pubkey(), 10_000_000).unwrap();
      
      // Create transfer instruction
      let ix = transfer(&from.pubkey(), &to.pubkey(), 1_000_000);
      let tx = Transaction::new(
          &[&from],
          Message::new(&[ix], Some(&from.pubkey())),
          svm.latest_blockhash(),
      );
      
      // Send transaction
      svm.send_transaction(tx).unwrap();
      
      // Verify balances
      assert_eq!(svm.get_balance(&to.pubkey()), 1_000_000);
  }
  ```

  ```typescript tab="TypeScript" theme={null}
  import { LiteSVM } from "litesvm";
  import {
    Keypair,
    Transaction,
    SystemProgram,
    LAMPORTS_PER_SOL,
  } from "@solana/web3.js";

  test("transfer SOL", () => {
    const svm = new LiteSVM();
    const from = new Keypair();
    const to = Keypair.generate().publicKey;
    
    // Airdrop SOL to sender
    svm.airdrop(from.publicKey, BigInt(LAMPORTS_PER_SOL));
    
    // Create transfer
    const tx = new Transaction();
    tx.recentBlockhash = svm.latestBlockhash();
    tx.add(
      SystemProgram.transfer({
        fromPubkey: from.publicKey,
        toPubkey: to,
        lamports: 1_000_000n,
      })
    );
    tx.sign(from);
    
    // Send transaction
    svm.sendTransaction(tx);
    
    // Verify balance
    expect(svm.getBalance(to)).toBe(1_000_000n);
  });
  ```

  ```python tab="Python" theme={null}
  from solders.keypair import Keypair
  from solders.litesvm import LiteSVM
  from solders.message import Message
  from solders.system_program import transfer
  from solders.transaction import VersionedTransaction

  def test_transfer():
      svm = LiteSVM()
      from_keypair = Keypair()
      to_pubkey = Keypair().pubkey()
      
      # Airdrop SOL
      svm.airdrop(from_keypair.pubkey(), 1_000_000_000)
      
      # Create transfer
      ix = transfer({
          "from_pubkey": from_keypair.pubkey(),
          "to_pubkey": to_pubkey,
          "lamports": 1_000_000,
      })
      
      msg = Message.new_with_blockhash(
          [ix],
          from_keypair.pubkey(),
          svm.latest_blockhash(),
      )
      tx = VersionedTransaction(msg, [from_keypair])
      
      # Send transaction
      svm.send_transaction(tx)
      
      # Verify balance
      assert svm.get_balance(to_pubkey) == 1_000_000
  ```
</Tabs>

## Testing Anchor Programs

To test an Anchor program with LiteSVM, you need to load the compiled program binary:

<Tabs items={["Rust", "TypeScript", "Python"]}>
  ```rust tab="Rust" theme={null}
  use litesvm::LiteSVM;
  use solana_sdk::{
      signature::Keypair,
      signer::Signer,
      instruction::{Instruction, AccountMeta},
      transaction::Transaction,
      message::Message,
  };

  #[test]
  fn test_anchor_program() {
      let mut svm = LiteSVM::new();
      let program_id = /* your program ID */;
      
      // Load program from compiled binary
      let program_data = include_bytes!("../../target/deploy/my_program.so");
      svm.add_program(program_id, program_data);
      
      // Set up accounts
      let user = Keypair::new();
      let my_account = Keypair::new();
      svm.airdrop(&user.pubkey(), 10_000_000).unwrap();
      
      // Create instruction (using Anchor IDL)
      let ix = Instruction {
          program_id,
          accounts: vec![
              AccountMeta::new(my_account.pubkey(), true),
              AccountMeta::new(user.pubkey(), true),
              AccountMeta::new_readonly(solana_sdk::system_program::ID, false),
          ],
          data: vec![/* instruction data */],
      };
      
      // Send transaction
      let tx = Transaction::new(
          &[&user, &my_account],
          Message::new(&[ix], Some(&user.pubkey())),
          svm.latest_blockhash(),
      );
      
      let result = svm.send_transaction(tx).unwrap();
      assert!(result.result.is_ok());
  }
  ```

  ```typescript tab="TypeScript" theme={null}
  import { LiteSVM } from "litesvm";
  import { Keypair, PublicKey, Transaction, TransactionInstruction } from "@solana/web3.js";
  import * as fs from "fs";

  test("anchor program", () => {
    const svm = new LiteSVM();
    const programId = new PublicKey("YourProgramID");
    
    // Load program binary
    svm.addProgramFromFile(
      programId,
      "target/deploy/my_program.so"
    );
    
    // Set up accounts
    const user = new Keypair();
    const myAccount = Keypair.generate();
    svm.airdrop(user.publicKey, 10_000_000n);
    
    // Create instruction
    const ix = new TransactionInstruction({
      programId,
      keys: [
        { pubkey: myAccount.publicKey, isSigner: true, isWritable: true },
        { pubkey: user.publicKey, isSigner: true, isWritable: true },
      ],
      data: Buffer.from([/* instruction data */]),
    });
    
    // Send transaction
    const tx = new Transaction();
    tx.recentBlockhash = svm.latestBlockhash();
    tx.add(ix);
    tx.sign(user, myAccount);
    
    const result = svm.sendTransaction(tx);
    expect(result).toBeTruthy();
  });
  ```

  ```python tab="Python" theme={null}
  from pathlib import Path
  from solders.keypair import Keypair
  from solders.litesvm import LiteSVM
  from solders.pubkey import Pubkey
  from solders.instruction import Instruction, AccountMeta
  from solders.message import Message
  from solders.transaction import VersionedTransaction

  def test_anchor_program():
      svm = LiteSVM()
      program_id = Pubkey.from_string("YourProgramID")
      
      # Load program
      svm.add_program_from_file(
          program_id,
          Path("target/deploy/my_program.so")
      )
      
      # Set up accounts
      user = Keypair()
      my_account = Keypair()
      svm.airdrop(user.pubkey(), 10_000_000)
      
      # Create instruction
      ix = Instruction(
          program_id,
          bytes([]),  # instruction data
          [
              AccountMeta(my_account.pubkey(), is_signer=True, is_writable=True),
              AccountMeta(user.pubkey(), is_signer=True, is_writable=True),
          ],
      )
      
      # Send transaction
      msg = Message.new_with_blockhash([ix], user.pubkey(), svm.latest_blockhash())
      tx = VersionedTransaction(msg, [user, my_account])
      
      result = svm.send_transaction(tx)
      assert result is not None
  ```
</Tabs>

## Time Travel

LiteSVM allows you to manipulate the Clock sysvar to test time-dependent logic:

<Tabs items={["Rust", "TypeScript", "Python"]}>
  ```rust tab="Rust" theme={null}
  use litesvm::LiteSVM;
  use solana_sdk::clock::Clock;

  #[test]
  fn test_time_travel() {
      let mut svm = LiteSVM::new();
      
      // Get current clock
      let mut clock = svm.get_sysvar::<Clock>();
      println!("Current time: {}", clock.unix_timestamp);
      
      // Advance time by 1 hour
      clock.unix_timestamp += 3600;
      svm.set_sysvar::<Clock>(&clock);
      
      // Verify new time
      let new_clock = svm.get_sysvar::<Clock>();
      assert_eq!(new_clock.unix_timestamp, clock.unix_timestamp);
  }
  ```

  ```typescript tab="TypeScript" theme={null}
  import { LiteSVM } from "litesvm";

  test("time travel", () => {
    const svm = new LiteSVM();
    
    // Get current clock
    const clock = svm.getClock();
    console.log("Current time:", clock.unixTimestamp);
    
    // Advance time by 1 hour
    clock.unixTimestamp = clock.unixTimestamp + 3600n;
    svm.setClock(clock);
    
    // Verify new time
    const newClock = svm.getClock();
    expect(newClock.unixTimestamp).toBe(clock.unixTimestamp);
  });
  ```

  ```python tab="Python" theme={null}
  from solders.litesvm import LiteSVM

  def test_time_travel():
      svm = LiteSVM()
      
      # Get current clock
      clock = svm.get_clock()
      print(f"Current time: {clock.unix_timestamp}")
      
      # Advance time by 1 hour
      clock.unix_timestamp += 3600
      svm.set_clock(clock)
      
      # Verify new time
      new_clock = svm.get_clock()
      assert new_clock.unix_timestamp == clock.unix_timestamp
  ```
</Tabs>

You can also jump to a specific slot:

```rust theme={null}
svm.warp_to_slot(1000);
```

## Arbitrary Account States

LiteSVM lets you write any account data, even states that would be impossible to achieve normally. This is useful for testing edge cases:

<Tabs items={["Rust", "TypeScript", "Python"]}>
  ```rust tab="Rust" theme={null}
  use litesvm::LiteSVM;
  use solana_sdk::{
      account::Account,
      pubkey::Pubkey,
  };
  use spl_token::state::{Account as TokenAccount, AccountState};

  #[test]
  fn test_arbitrary_token_balance() {
      let mut svm = LiteSVM::new();
      let owner = Pubkey::new_unique();
      let token_account = Pubkey::new_unique();
      
      // Create token account with arbitrary balance
      let account_data = TokenAccount {
          mint: Pubkey::new_unique(),
          owner,
          amount: 1_000_000_000_000, // 1 trillion tokens!
          delegate: None,
          state: AccountState::Initialized,
          is_native: None,
          delegated_amount: 0,
          close_authority: None,
      };
      
      let mut data = vec![0u8; TokenAccount::LEN];
      TokenAccount::pack(account_data, &mut data).unwrap();
      
      svm.set_account(
          token_account,
          Account {
              lamports: 1_000_000,
              data,
              owner: spl_token::ID,
              executable: false,
              rent_epoch: 0,
          },
      ).unwrap();
      
      // Now test with this account
      let acc = svm.get_account(&token_account).unwrap();
      let token_acc = TokenAccount::unpack(&acc.data).unwrap();
      assert_eq!(token_acc.amount, 1_000_000_000_000);
  }
  ```

  ```typescript tab="TypeScript" theme={null}
  import { LiteSVM } from "litesvm";
  import { PublicKey } from "@solana/web3.js";
  import { AccountLayout, TOKEN_PROGRAM_ID } from "@solana/spl-token";

  test("arbitrary token balance", () => {
    const svm = new LiteSVM();
    const owner = PublicKey.unique();
    const mint = PublicKey.unique();
    const tokenAccount = PublicKey.unique();
    
    // Create token account data
    const accountData = Buffer.alloc(165);
    AccountLayout.encode(
      {
        mint,
        owner,
        amount: 1_000_000_000_000n,
        delegateOption: 0,
        delegate: PublicKey.default,
        state: 1,
        isNativeOption: 0,
        isNative: 0n,
        delegatedAmount: 0n,
        closeAuthorityOption: 0,
        closeAuthority: PublicKey.default,
      },
      accountData
    );
    
    // Set the account
    svm.setAccount(tokenAccount, {
      lamports: 1_000_000,
      data: accountData,
      owner: TOKEN_PROGRAM_ID,
      executable: false,
    });
    
    // Verify
    const acc = svm.getAccount(tokenAccount);
    const decoded = AccountLayout.decode(acc.data);
    expect(decoded.amount).toBe(1_000_000_000_000n);
  });
  ```

  ```python tab="Python" theme={null}
  from solders.account import Account
  from solders.litesvm import LiteSVM
  from solders.pubkey import Pubkey
  from solders.token import ID as TOKEN_PROGRAM_ID
  from solders.token.state import TokenAccount, TokenAccountState

  def test_arbitrary_token_balance():
      svm = LiteSVM()
      owner = Pubkey.new_unique()
      mint = Pubkey.new_unique()
      token_account_pubkey = Pubkey.new_unique()
      
      # Create token account with huge balance
      token_account = TokenAccount(
          mint=mint,
          owner=owner,
          amount=1_000_000_000_000,
          delegate=None,
          state=TokenAccountState.Initialized,
          is_native=None,
          delegated_amount=0,
          close_authority=None,
      )
      
      # Set account in SVM
      svm.set_account(
          token_account_pubkey,
          Account(
              lamports=1_000_000,
              data=bytes(token_account),
              owner=TOKEN_PROGRAM_ID,
              executable=False,
          ),
      )
      
      # Verify
      acc = svm.get_account(token_account_pubkey)
      decoded = TokenAccount.from_bytes(acc.data)
      assert decoded.amount == 1_000_000_000_000
  ```
</Tabs>

## Advanced Features

### Compute Budget Control

```rust theme={null}
let mut svm = LiteSVM::new()
    .with_compute_budget(1_000_000); // Set max compute units
```

### Disable Signature Verification

```rust theme={null}
let mut svm = LiteSVM::new()
    .with_sigverify(false); // Skip signature checks (faster tests)
```

### Transaction History

```rust theme={null}
let tx_result = svm.send_transaction(tx).unwrap();
let signature = tx_result.signature;

// Later, retrieve transaction
let stored_tx = svm.get_transaction(signature);
```

## Performance Comparison

| Framework             | Startup Time | Test Speed | Resource Usage |
| --------------------- | ------------ | ---------- | -------------- |
| LiteSVM               | \~0ms        | Fastest    | Minimal        |
| solana-program-test   | \~50ms       | Fast       | Low            |
| solana-test-validator | \~5000ms     | Slow       | High           |

## Best Practices

1. **Use LiteSVM for unit tests** - Test individual instructions quickly
2. **Use test-validator for integration** - Test full workflows and RPC interactions
3. **Mock account states** - Use arbitrary accounts to test edge cases
4. **Time travel for scheduling** - Test time-locked features without waiting
5. **Parallel tests** - LiteSVM tests can run in parallel safely

## Limitations

* **No RPC methods** - LiteSVM doesn't expose RPC endpoints
* **Simplified validator** - Doesn't simulate all validator behaviors
* **No cross-program invocation limits** - May behave differently than production

For testing that requires full validator fidelity, use `solana-test-validator`.

## Next Steps

* Learn about \[Mollusktesting/mollusk) for even lighter Rust testing
* Explore \[Testing Overviewtesting/overview) for testing strategies
* Check out the [LiteSVM GitHub](https://github.com/LiteSVM/litesvm) for more examples
