---
title: Quick Start
description:
  Learn how to use anchor-litesvm for testing Anchor programs with simplified
  syntax
---

<div className="flex items-center gap-3 mb-6">
  <a
    href="https://crates.io/crates/anchor-litesvm"
    target="_blank"
    rel="noopener noreferrer"
    className="inline-flex items-center gap-2 px-3 py-1.5 bg-fd-muted/50 hover:bg-fd-muted rounded-lg text-sm font-medium transition-colors border border-fd-border/50"
  >
    <svg
      xmlns="http://www.w3.org/2000/svg"
      viewBox="0 0 512 512"
      className="w-4 h-4"
      fill="currentColor"
    >
      <path d="M239.1 6.3l-208 78c-18.7 7-31.1 25-31.1 45v225.1c0 18.2 10.3 34.8 26.5 42.9l208 104c13.5 6.8 29.4 6.8 42.9 0l208-104c16.3-8.1 26.5-24.8 26.5-42.9V129.3c0-20-12.4-37.9-31.1-44.9l-208-78C262 2.2 250 2.2 239.1 6.3zM256 68.4l192 72v1.1l-192 78-192-78v-1.1l192-72zm32 356V275.5l160-65v133.9l-160 80z" />
    </svg>
    View <code>anchor-litesvm</code> on crates.io
  </a>
</div>

## Installation

Add the needed dependencies:

```bash
cargo add --dev anchor-litesvm litesvm litesvm-utils
```

## What is anchor-litesvm?

The `anchor-litesvm` crate provides a **simplified syntax similar to
anchor-client** but without RPC overhead. It achieves **78% code reduction**
compared to raw LiteSVM while maintaining type safety with Anchor types.

<Steps>
<Step>
**AnchorContext**
- Production-compatible test context
- Same API patterns as anchor-client
- Manages LiteSVM instance, payer, and program
- Execute instructions without RPC overhead
</Step>

<Step>
  **Program API** - Fluent instruction building - Type-safe account and argument
  handling - Familiar anchor-client syntax
</Step>

<Step>
  **Account Deserialization** - Fetch and deserialize Anchor accounts -
  Automatic discriminator handling - Support for PDAs and custom layouts
</Step>

<Step>
**Event Parsing**
- Parse events from transaction logs
- Assert event emission
- Type-safe event deserialization
</Step>
</Steps>

## Quick Example

With Anchor 1.0, use `declare_program!` to generate client types from your
program's IDL. This macro creates `client::accounts::*` and `client::args::*`
modules for type-safe instruction building:

```rust
use anchor_litesvm::AnchorLiteSVM;
use anchor_litesvm::{AssertionHelpers, TestHelpers};
use anchor_lang::system_program;
use solana_sdk::signature::{read_keypair_file, Signer};

// Generate client types from your program's IDL
anchor_lang::declare_program!(my_program);

#[test]
fn test_anchor_program() {
    // One-line setup — reads program keypair for the correct ID
    let program_keypair = read_keypair_file("target/deploy/my_program-keypair.json").unwrap();
    let mut ctx = AnchorLiteSVM::build_with_program(
        program_keypair.pubkey(),
        include_bytes!("../target/deploy/my_program.so"),
    );

    // Create a funded account via TestHelpers on ctx.svm
    let user = ctx.svm.create_funded_account(10_000_000_000).unwrap();

    // Derive PDA
    let seed: u64 = 42;
    let pda = ctx.svm.get_pda(
        &[b"user", user.pubkey().as_ref(), &seed.to_le_bytes()],
        &program_keypair.pubkey(),
    );

    // Build instruction using generated client types
    let ix = ctx.program()
        .accounts(my_program::client::accounts::Initialize {
            user: user.pubkey(),
            user_account: pda,
            system_program: system_program::ID,
        })
        .args(my_program::client::args::Initialize {
            seed,
            name: "test".to_string(),
        })
        .instruction()
        .unwrap();

    // Execute and assert in one chain
    ctx.execute_instruction(ix, &[&user])
        .unwrap()
        .assert_success();

    // Fetch and deserialize the account
    let account: my_program::MyAccount = ctx.get_account(&pda).unwrap();
    assert_eq!(account.name, "test");
}
```

<Callout type="info">
  `declare_program!(my_program)` reads the IDL from `target/idl/my_program.json`
  at compile time and generates the `client::accounts::*` and `client::args::*`
  modules. This requires building your program first.
</Callout>

## Comparison: Raw LiteSVM vs anchor-litesvm

### Before (Raw LiteSVM)

```rust
use litesvm::LiteSVM;
use solana_keypair::Keypair;
use solana_signer::Signer;
use solana_program::instruction::{AccountMeta, Instruction};
use solana_message::Message;
use solana_transaction::Transaction;

let mut svm = LiteSVM::new();
svm.add_program(program_id, program_bytes).unwrap();

let payer = Keypair::new();
svm.airdrop(&payer.pubkey(), 10_000_000_000).unwrap();

// Manually compute 8-byte discriminator
let discriminator = {
    let mut hasher = sha2::Sha256::new();
    hasher.update(b"global:initialize");
    let result = hasher.finalize();
    result[..8].to_vec()
};

// Manually serialize args and build instruction
let mut data = discriminator;
data.extend_from_slice(&borsh::to_vec(&args).unwrap());

let accounts = vec![
    AccountMeta::new(user.pubkey(), true),
    AccountMeta::new(user_pda, false),
    AccountMeta::new_readonly(system_program::id(), false),
];

let ix = Instruction::new_with_bytes(program_id, &data, accounts);
let tx = Transaction::new_signed_with_payer(
    &[ix],
    Some(&payer.pubkey()),
    &[&payer],
    svm.latest_blockhash(),
);
svm.send_transaction(tx).unwrap();

// Manually deserialize with discriminator skip
let account_data = svm.get_account(&pda).unwrap().data;
let account: UserAccount = UserAccount::try_deserialize(
    &mut &account_data[8..]
).unwrap();
```

### After (anchor-litesvm)

```rust
use anchor_litesvm::AnchorLiteSVM;

anchor_lang::declare_program!(my_program);

let mut ctx = AnchorLiteSVM::build_with_program(program_id, program_bytes);
let user = ctx.svm.create_funded_account(10_000_000_000).unwrap();

let ix = ctx.program()
    .accounts(my_program::client::accounts::Initialize {
        user: user.pubkey(),
        user_account: user_pda,
        system_program: anchor_lang::system_program::ID,
    })
    .args(my_program::client::args::Initialize { name: "test".to_string() })
    .instruction()
    .unwrap();

ctx.execute_instruction(ix, &[&user]).unwrap().assert_success();

let account: my_program::UserAccount = ctx.get_account(&user_pda).unwrap();
```

## Key Components

### AnchorLiteSVM Builder

| Method                          | Description                    |
| ------------------------------- | ------------------------------ |
| `new()`                         | Creates a new builder instance |
| `with_payer(keypair)`           | Sets a custom payer keypair    |
| `deploy_program(id, bytes)`     | Adds a program to deploy       |
| `build()`                       | Builds the AnchorContext       |
| `build_with_program(id, bytes)` | Convenience for single program |
| `build_with_programs(programs)` | Deploy multiple programs       |

### AnchorContext

| Method                               | Description                                                       |
| ------------------------------------ | ----------------------------------------------------------------- |
| `svm`                                | Direct access to the underlying `LiteSVM` instance (public field) |
| `program_id`                         | The program ID (public field)                                     |
| `program()`                          | Returns `Program` for instruction building                        |
| `payer()`                            | Get the payer `Keypair`                                           |
| `execute_instruction(ix, signers)`   | Execute a single instruction                                      |
| `execute_instructions(ixs, signers)` | Execute multiple instructions in one tx                           |
| `send_and_confirm_transaction(&tx)`  | Send a raw transaction                                            |
| `get_account<T>(pubkey)`             | Fetch and deserialize an Anchor account                           |
| `get_account_unchecked<T>(pubkey)`   | Fetch without discriminator check                                 |
| `create_funded_account(lamports)`    | Create and fund a new keypair                                     |
| `airdrop(pubkey, lamports)`          | Airdrop SOL to an address                                         |
| `latest_blockhash()`                 | Get the current blockhash                                         |
| `account_exists(pubkey)`             | Check if an account exists                                        |
| `deploy_program(id, bytes)`          | Deploy an additional program (via `ProgramTestExt`)               |

### Program

| Method               | Description                                            |
| -------------------- | ------------------------------------------------------ |
| `accounts(accounts)` | Set instruction accounts (any `ToAccountMetas` type)   |
| `args(args)`         | Set instruction arguments (any `InstructionData` type) |
| `instruction()`      | Build the final `Instruction`                          |
| `id()`               | Get the program ID                                     |

### ctx.svm — TestHelpers & AssertionHelpers

`ctx.svm` is a public `LiteSVM` field with `TestHelpers` and `AssertionHelpers`
traits available via `litesvm-utils`:

| Method                                                    | Description               |
| --------------------------------------------------------- | ------------------------- |
| `ctx.svm.create_funded_account(lamports)`                 | Create and fund a keypair |
| `ctx.svm.create_token_mint(authority, decimals)`          | Create an SPL token mint  |
| `ctx.svm.create_associated_token_account(mint, owner)`    | Create an ATA             |
| `ctx.svm.mint_to(mint, token_account, authority, amount)` | Mint tokens               |
| `ctx.svm.get_pda(seeds, program_id)`                      | Derive a PDA address      |
| `ctx.svm.get_pda_with_bump(seeds, program_id)`            | Derive PDA with bump seed |
| `ctx.svm.assert_token_balance(token_account, expected)`   | Assert token balance      |
| `ctx.svm.assert_account_closed(pubkey)`                   | Assert account was closed |
| `ctx.svm.assert_sol_balance(pubkey, expected)`            | Assert SOL balance        |

## Troubleshooting

### Common Errors

| Error                   | Cause                                       | Solution                                                               |
| ----------------------- | ------------------------------------------- | ---------------------------------------------------------------------- |
| `AccountNotFound`       | Account doesn't exist                       | Ensure account is created before fetching                              |
| `DiscriminatorMismatch` | Wrong account type                          | Verify you're using the correct account struct                         |
| `DeserializationError`  | Invalid account data                        | Check account was initialized correctly                                |
| No programs added       | Called `build()` without `deploy_program()` | Add at least one program before building                               |
| Missing client types    | `declare_program!` not called               | Run `anchor build` first to generate IDL, then call `declare_program!` |
