Exploring Anchor v0.31.0: Key Features and Enhancements
Mitch

Mitch @stelmitchay

Joined:
Mar 13, 2025

Exploring Anchor v0.31.0: Key Features and Enhancements

Publish Date: Mar 18
0 0

INTRODUCTION

Anchor has long been a cornerstone in Solana development, for writing, testing, deploying, and interacting with Solana programs.The release of version 0.31.0 marks a significant milestone(this is the last major update before v1 is actually released) 0.31.0 introduces more enhancements to development workflows, compatibility improvements, and updates to its core features.

This article explores the technical advancements in Anchor v0.31.0, including new features like dynamic discriminator support and improved IDL generation workflows, alongside bug fixes that streamline program interaction. Let’s dive into everything you need to know about this update with detailed explanations and code examples.

Custom Discriminators

Anchor automatically generated an 8-byte discriminator for each account, limiting flexibility when integrating with other programs. With this update, you can now define your own discriminator values, including using zero-length discriminators where needed.

Why is this useful?

  • Allows better interoperability with non-Anchor programs.
  • Provides more control over account structure.
  • Reduces overhead when specific discriminators are unnecessary.

Example on setting a custom discriminator

#[account(discriminator = 1)]
pub struct MyAccount{
    //define account fields
}
Enter fullscreen mode Exit fullscreen mode

This ensures that MyAccount is identified using the discriminator 1, rather than the default auto-generated one.

LazyAccount: Optimized Deserialization

This experimental feature introduces a new account wrapper that defers deserialization until the account data is accessed. It improves performance with large accounts and optimizes execution time in complex transactions.

Why is this useful?

  • Improves performance when working with large accounts.
  • Reduces unnecessary deserialization overhead.
  • Optimizes execution time in complex transactions.

Example

#[derive(Accounts)]
pub struct MyInstruction<'info> {
    #[account(lazy)]
    pub my_account: LazyAccount<'info, MyAccount>,
}
Enter fullscreen mode Exit fullscreen mode

With this implementation, my_account will only be deserialized if its data is accessed, saving computational resources.

To enable this feature, you need to activate it in Cargo.toml:

anchor-lang = { version = "0.31.0", features = ["lazy-account"] }
Enter fullscreen mode Exit fullscreen mode

Conditional Compilation for Instructions

Anchor now supports Rust’s cfg attributes for conditionally compiling instruction functions. This allows feature-gated logic within programs.

#[cfg(feature = "experimental")]
pub fn my_instruction(ctx: Context<MyInstruction>) -> Result<()> {
    // Implementation only available when "experimental" feature is enabled
    Ok(())
}
Enter fullscreen mode Exit fullscreen mode

Improved Account Resolution Errors

Previously, Anchor returned vague error messages when accounts were missing during validation. Now, it provides more detailed error messages,

before

Account validation failed
Enter fullscreen mode Exit fullscreen mode

now

Missing: token_account (AssociatedToken)
Enter fullscreen mode Exit fullscreen mode

Mock RPC for More Reliable Testing

Anchor’s RPC client previously depended on live network conditions, causing inconsistent test results.You can now use new_mock to simulate specific states in tests. This help dependency on live Solana clusters and ensuring deterministic test outcomes.

before

let client = RpcClient::new(cluster_url); // Unpredictable network responses
Enter fullscreen mode Exit fullscreen mode

after

let client = RpcClient::new_mock("airdrop=100"); // Controlled environment
Enter fullscreen mode Exit fullscreen mode

New Builder Struct for Programmatic IDL Creation

You can now dynamically generate IDLs using the IdlBuilder struct instead of manually defining JSON files.

before

{
  "name": "my_program",
  "instructions": [
    {
      "name": "initialize",
      "accounts": ["param1", "param2"]
    }
  ]
}

Enter fullscreen mode Exit fullscreen mode

now

let idl = IdlBuilder::new()
    .name("MyProgram")
    .instruction("initialize", vec!["param1", "param2"])
    .build();
Enter fullscreen mode Exit fullscreen mode

In addition to introducing powerful new features, Anchor v0.31.0 also brings a host of improvements and optimizations aimed at enhancing developer workflows and ensuring compatibility with evolving Solana toolchains. Let’s explore these updates in detail.

Improvements in Anchor 0.31.0

🚀 Performance Enhancements

  • Reduced Stack Memory Overhead: Previously, initializing multiple accounts with init consumed significant stack space, potentially causing stack overflows in complex programs. This update moves init processing into a separate stack frame, reducing stack usage without requiring syntax changes.
🛠️ Developer Workflow Enhancements
  • Automatic Legacy IDL Conversion : Legacy IDLs (pre-Anchor v0.30) are now automatically converted to the new format during builds, eliminating the need for manual anchor idl convert commands.
    Note: The anchor idl fetch command does not support auto-conversion..

  • Shell Completions for Anchor CLI : Developers using the can now enable shell autocompletion for faster command execution.

🧪 CLI & Testing Improvements
  • Passing Cargo Args to IDL Build

    You can now pass Cargo feature flags when building the IDL.This ensures that the IDL is built with specific features enabled

    anchor build -- --features my-feature
    
  • --no-idl Flag for Tests

    If program logic remains unchanged but tests need to run frequently, this flag skips rebuilding the IDL, saving time:

    anchor test --no-idl
    
  • Mollusk Test Template

    Initialize an Anchor workspace with pre-configured tests using this new template:

    anchor init my-program --test-template mollusk
    

    This template provides pre-configured tests, making it easier to start new projects with testing in mind.

  • Enhanced anchor clean command

    Previously, anchor clean only removed build artifacts.
    anchor clean it now also removes the .anchor directory, behaving like cargo clean but keeping program keypairs intact.

Compatibility Updates

  • ⚠️ Deprecation Warning (Solana v1.18.19)

    Solana binaries are being renamed to Agave, and solana-install has been deprecated as of Solana v1.18.19 If you're using an older version of Anchor, this can cause parsing failures when running Solana-related commands.

    If you attempt to use solana-install, you will now see this warning:

    solana-install is deprecated and will be discontinued when v1.18 is no longer supported. 
    Please switch to Agave: https://github.com/anza-xyz/agave/wiki/Agave-Transition
    

    To avoid issues, Anchor 0.31.0 automatically installs and switches to agave-install when you specify solana_version greater than 1.18.19 in Anchor.toml.

How to Ensure Agave is Used

Modify your Anchor.toml like this:

[toolchain]
solana_version = "2.1.0"
Enter fullscreen mode Exit fullscreen mode

Alternatively, you can manually install Agave with:


sh -c "$(curl -sSfL https://release.anza.xyz/v2.1.0/install)"

  • ‼️ Solana-Program Warning

    Adding solana-program as a dependency might cause conflicts between Solana v1 and v2 crates. If solana-program is present in your dependencies, you’ll now see this warning:

    
    WARNING: Adding `solana-program` as a separate dependency might cause conflicts.
    To solve, remove the `solana-program` dependency and use the exported crate from `anchor-lang`.
    `use solana_program` becomes `use anchor_lang::solana_program`.
    

    ⚙️ How to Fix This Issue
    Simply remove solana-program from your Cargo.toml:

    [dependencies]
    # Remove this:
    # solana-program = "2.0.0"
    

    Use this instead:
    anchor-lang = "0.31.0"
    Then, update your imports:

    // OLD
    use solana_program::pubkey::Pubkey;
    
    // NEW (correct way)
    use anchor_lang::solana_program::pubkey::Pubkey;
    

How to upgrade

  • Install the latest version of avm:

cargo install --git https://github.com/coral-xyz/anchor avm --force

This will allow installing Anchor CLI without having to compile from source.

  • Update anchor-cli: avm install 0.31.0
  • Update Anchor crate(s) to 0.31.0.
  • Update TS package(s) to 0.31.0.

Install from binary

avm install now downloads binaries from GitHub by default.

The following build targets are supported:

  • aarch64-apple-darwin
  • x86_64-unknown-linux-gnu
  • x86_64-apple-darwin
  • x86_64-pc-windows-msvc

You can add the --from-source flag to the install command if that's preferred (or required due to unsupported platform)

Impact on Development Workflow

Building on the improvements introduced in Anchor 0.31.0, this release significantly enhances the development workflow by streamlining debugging, testing, and configuration processes. The clearer error messages and more reliable testing tools reduce the time spent diagnosing issues, allowing teams to focus on feature development.

Performance optimizations, such as lazy deserialization for accounts, improve the efficiency of complex programs. This not only reduces computational overhead during development but also enhances deployment performance. For instance, lazy deserialization is particularly beneficial in read-heavy applications where accounts are frequently accessed but rarely modified.

The inclusion of features like shell autocompletion for the Anchor CLI and expanded support for conditional compilation makes the framework more intuitive and adaptable to specific project needs. These updates collectively enhance productivity and reduce the learning curve for both new and experienced developers. For new developers, the simplified program initialization and configuration process, combined with improved documentation and tools, lower the barrier to entry by providing a more straightforward path to building Solana programs.

Compatibility and Migration

Anchor 0.31.0 is designed with backward compatibility in mind, ensuring a seamless transition for existing projects while future proofing applications against upcoming ecosystem changes. The automatic conversion of legacy IDLs simplifies migration efforts, allowing you to upgrade without extensive manual intervention. This ensures that older projects can leverage the latest features without requiring significant refactoring.

The framework also adapts seamlessly to Solana's evolving toolchain by supporting Agave binaries for Solana v1.18+ users, eliminating potential parsing failures caused by deprecated tools like solana-install Configuring projects to use the latest Solana versions is straightforward, ensuring compatibility with future updates. The migration process is well-documented, with clear instructions for upgrading both Rust-based programs and TypeScript SDKs, minimizing downtime and ensuring project stability throughout the transition.

✅ Conclusion

In conclusion Anchor 0.31.0 is really more than just an update this release makes building on Solana faster, easier, and even more efficient. The reduced learning curve, enhanced CLI, and more reliable testing workflows mean both newcomers and experienced builders can work smarter, not harder. With v1 on the horizon, Anchor’s trajectory suggests continued focus on performance, flexibility, and developer experience. Expect future releases to build on these foundations, potentially expanding cross program integration capabilities and refining testing frameworks to meet the evolving needs of the ecosystem.

For a deeper dive you can check out the
Anchor 0.31.0 release notes and the full CHANGELOG

Comments 0 total

    Add comment