SolanaAnchorRustBlockchain13 min readUpdated

What Is Anchor? The Solana Development Framework

By Mudassir Khan — Agentic AI Consultant & AI Systems Architect, Islamabad, Pakistan

Cover illustration for: What Is Anchor? The Solana Development Framework

Writing Solana programs without a framework requires manually parsing instruction data, validating account ownership, and handling serialization. Anchor wraps all of that into four macros. It is the standard for Solana development in 2025 and beyond.

Before reading this guide, make sure you are comfortable with Rust ownership for Solana. Anchor programs are still Rust programs, and the borrow checker applies to every handler you write.

Section 1

What is Anchor?

A framework that turns infrastructure boilerplate into declarative macros.

Quick answer

What is Anchor for Solana? Anchor is a Rust framework for writing Solana programs. It generates boilerplate account validation, serialization, and error handling code through macros, so you write business logic rather than infrastructure.

Anchor was created by Armani Ferrante and is maintained by Coral Finance. The framework sits as a thin layer over the raw Solana program runtime. Your program still compiles to BPF bytecode and runs on validators — Anchor just removes roughly 80% of the repetitive code.

The framework generates a JSON IDL (Interface Definition Language) file from your program. Client SDKs in TypeScript use this IDL to call your program with full type safety, which eliminates a large class of integration bugs.

Anchor is opinionated

Anchor enforces a specific program structure: one #[program] module, #[derive(Accounts)] structs for each instruction, and #[account] structs for on-chain state. This makes Anchor code instantly recognizable and auditable — a security firm reviewing your program knows exactly where to look.

Core concept

Four Macros That Do the Heavy Lifting

Each macro targets a specific category of boilerplate. Together they cover almost everything a Solana program needs.

#[program]

Marks the module containing your instruction handlers. Anchor routes incoming instruction discriminators to the right handler function automatically. Without Anchor, you write a match statement over raw bytes.

#[derive(Accounts)]

Applied to a struct that lists all accounts an instruction needs. Anchor validates ownership, signer status, and constraints declared in the struct fields before your handler runs.

#[account]

Applied to a struct representing on-chain state. Anchor generates Borsh serialization and deserialization automatically and adds an 8-byte discriminator prefix so account types cannot be confused at runtime.

Events and Errors

Anchor provides #[event] for emitting typed logs and #[error_code] for defining human-readable error variants. Both improve debuggability significantly compared to numeric error codes in raw programs.

Section 3

Anchor vs raw Solana

A side-by-side look at what changes when you add Anchor.

Quick answer

Should I use Anchor or write raw Solana programs? Use Anchor for almost everything. Raw Solana programs are only warranted for ultra-tight optimization (e.g. high-frequency AMMs) where every byte and instruction counts.

TaskRaw SolanaWith Anchor
Account ownership checkManual if / return Err()#[account(owner = token_program)]
Instruction routingMatch on discriminator bytesAutomatic via #[program] macro
SerializationManual Borsh impl#[account] generates it
PDA validationManual seeds + bump check#[account(seeds=[...], bump)]
Error messagesNumeric codes only#[error_code] enum with messages

Anchor adds ~65KB to your program binary

This is usually not a problem — Solana's max program size is 10MB on-chain. But if you are writing a tiny utility program where size matters, raw Solana might be preferable. For any program with real business logic, the safety benefits of Anchor far outweigh the binary size cost.

Section 4

Installation and setup

Install Rust, Solana CLI, and Anchor Version Manager in that order.

Quick answer

How do I install Anchor? Install Rust, Solana CLI, and then Anchor Version Manager (avm). Use avm to install and switch between Anchor versions.

bash
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Install Solana CLI
sh -c "$(curl -sSfL https://release.solana.com/stable/install)"

# Install Anchor Version Manager
cargo install --git https://github.com/coral-xyz/anchor avm --locked --force

# Install and use latest Anchor
avm install latest
avm use latest

# Verify
anchor --version

Once Anchor is installed, create a new project with anchor init. This scaffolds the full project structure including a programs directory, a tests directory, and an Anchor.toml configuration file.

bash
anchor init my-counter
cd my-counter

Full example

A Counter Program in Anchor

This program creates a counter account and increments it. It demonstrates all four Anchor abstractions together.

This is the canonical Anchor example. It has two instructions: initialize (creates a counter account with count set to 0) and increment (adds 1 to count). Study the Initialize struct carefully — every field maps directly to an account the client must pass, and every constraint is enforced before the handler runs.

rust
use anchor_lang::prelude::*;

declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");

#[program]
pub mod my_counter {
    use super::*;

    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        ctx.accounts.counter.count = 0;
        Ok(())
    }

    pub fn increment(ctx: Context<Increment>) -> Result<()> {
        ctx.accounts.counter.count += 1;
        Ok(())
    }
}

#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(
        init,
        payer = user,
        space = 8 + Counter::INIT_SPACE
    )]
    pub counter: Account<'info, Counter>,
    #[account(mut)]
    pub user: Signer<'info>,
    pub system_program: Program<'info, System>,
}

#[derive(Accounts)]
pub struct Increment<'info> {
    #[account(mut)]
    pub counter: Account<'info, Counter>,
}

#[account]
#[derive(InitSpace)]
pub struct Counter {
    pub count: u64,
}

The TypeScript test below uses the auto-generated client types. Notice that the method names (initialize, increment) match the Rust handler names exactly — Anchor generates the mapping from the IDL.

typescript
import * as anchor from "@coral-xyz/anchor";
import { Program } from "@coral-xyz/anchor";
import { MyCounter } from "../target/types/my_counter";

describe("my-counter", () => {
  const provider = anchor.AnchorProvider.env();
  anchor.setProvider(provider);
  const program = anchor.workspace.MyCounter as Program<MyCounter>;

  it("initializes the counter", async () => {
    const counter = anchor.web3.Keypair.generate();
    await program.methods
      .initialize()
      .accounts({ counter: counter.publicKey })
      .signers([counter])
      .rpc();

    const account = await program.account.counter.fetch(counter.publicKey);
    console.log("Count:", account.count.toString()); // 0
  });

  it("increments the counter", async () => {
    const counter = anchor.web3.Keypair.generate();
    // initialize first...
    await program.methods
      .increment()
      .accounts({ counter: counter.publicKey })
      .rpc();

    const account = await program.account.counter.fetch(counter.publicKey);
    console.log("Count:", account.count.toString()); // 1
  });
});

Build and test locally with the Anchor CLI. The test command spins up a local validator automatically.

bash
anchor build
anchor test

For a complete walkthrough of deploying this program and calling it from a frontend, see the Solana Hello World with Anchor guide. And if you want to go deeper on account constraints, the Anchor accounts deep-dive covers init, has_one, seeds, bump, and close in detail.

Anchor vs raw Solana program structure comparison
Anchor sits between your business logic and the raw Solana runtime
Anchor's six core features
The six things Anchor handles automatically

Section 6

Frequently asked questions

Common questions about Anchor from developers new to Solana.

What is Anchor in Solana?

Anchor is a Rust framework for building Solana programs. It uses procedural macros to generate account validation, Borsh serialization, instruction routing, and error handling code. This removes the boilerplate and lets developers focus on business logic.

Do I need Anchor to write Solana programs?

No. You can write raw Solana programs using the solana-program crate directly. But Anchor handles a large amount of repetitive code automatically, which reduces bugs and speeds development. For most projects, Anchor is the better choice.

What is #[derive(Accounts)] in Anchor?

#[derive(Accounts)] is an Anchor macro applied to a struct. It tells Anchor to generate account validation code for the instruction. Each field in the struct maps to one account, and you can add constraints (init, mut, has_one, seeds, bump) that Anchor enforces before your handler runs.

Is Anchor safe to use in production?

Yes. Anchor is used in production by Orca, Marinade, Metaplex, and hundreds of other Solana protocols. The framework has been audited multiple times. Using Anchor can improve security versus raw programs because account validation constraints are explicit and reviewed as part of the struct definition.

How does Anchor generate the discriminator?

When you apply #[account] to a struct, Anchor computes a deterministic 8-byte discriminator by hashing 'account:<StructName>' with SHA-256 and taking the first 8 bytes. This discriminator is written as the first 8 bytes of the account's data, allowing Anchor to verify the account type before deserializing.

Written by Mudassir Khan

Agentic AI consultant and AI systems architect based in Islamabad, Pakistan. CEO of Cube A Cloud. 38+ agentic AI launches delivered for global founders and CTOs.

View blockchain development serviceSee ChainTrust case study

Related service

Blockchain Development

See scope & pricing →

Related case study

ChainTrust Compliance Engine

Read case study →

More on this topic

Need an AI systems architect?

Book a 30-minute architecture call. I will sketch the high-level design for your use case and give you an honest view of the trade-offs.

Book a strategy call →