Anchor vs Native
Native Solana programs use entrypoint! and manual account parsing. Anchor generates dispatch, discriminators, account validation, and IDL from macros at the cost of binary size and some CU overhead.
Recipe
| Concern | Native | Anchor 0.32.1 |
|---|---|---|
| Entrypoint | Hand-written | Generated by #[program] |
| Account checks | Manual in handler | #[derive(Accounts)] constraints |
| Client types | Hand-maintained | IDL / declare_program! |
| Errors | Custom u32 codes | #[error_code] + IDL mapping |
When to reach for this: You choose a framework for a new program or debate migrating existing native code.
Working Example
// Anchor: validation is declarative
#[derive(Accounts)]
pub struct Increment<'info> {
#[account(mut, has_one = authority)]
pub counter: Account<'info, Counter>,
pub authority: Signer<'info>,
}
// Native equivalent: manual checks in every handler
// - verify signer
// - verify owner == program_id
// - verify counter.authority == authority.key()
// - deserialize with discriminatorWhat this demonstrates:
- Anchor adds discriminator checks on account data automatically
- IDL enables
declare_program!CPI modules in 0.32 - Native/Pinocchio wins on CU for hot paths
- Mixed systems can CPI across frameworks with correct account metas
Deep Dive
What Anchor Generates
- Instruction dispatch - 8-byte discriminators and Borsh deserialization.
- Account validation - Owner, signer, mut, seeds, init, token constraints.
- IDL JSON - Instructions, accounts, types, errors for clients.
- CPI helpers - Especially via
anchor-splanddeclare_program!.
When Native Still Wins
- Extreme CU budgets (high-frequency AMM math).
- Minimal deploy size requirements.
- Programs with no off-chain typed client needs.
Gotchas
- Assuming Anchor removes all security work - Custom invariants still need
constraintandrequire!.. Fix: Model threats explicitly. - Mixing frameworks in one crate - Unsupported; pick one per program.. Fix: Split crates or go native.
- Blind migration native→Anchor - Account layouts must match discriminators.. Fix: Plan data migration instructions.
- Ignoring CU regression - Anchor overhead matters at scale.. Fix: Profile with
solana program logand CU meters. - Skipping IDL for Anchor programs - Defeats main reason to use Anchor.. Fix: Publish IDL with every release.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| Pinocchio + manual layout | CU-sensitive code | You want Anchor account macros |
| Steel framework | Structured native patterns | You need Anchor ecosystem IDL tooling |
| Stay native | Tiny program, no client codegen | Rich account validation needs |
FAQs
What Anchor version does this site use?
0.32.1 for anchor-lang, Anchor CLI, and examples in this section.
Do I need Solana CLI alongside Anchor?
Yes. Solana CLI 3.0.10 handles keypairs, airdrops, and solana program inspection.
Where does the IDL live after build?
target/idl/<program>.json in your workspace.
Can I mix UncheckedAccount with Signer?
Yes, but every unchecked field needs explicit constraints or handler checks.
How do I test without devnet?
Use anchor test with Surfpool 0.12.0 or LiteSVM 0.6.x in CI.
What is the 8-byte prefix on account data?
Anchor account discriminator; do not strip it when sizing space.
Should I commit generated IDL?
Yes, or publish on-chain IDL so clients have a canonical source.
How do I debug constraint failures?
Run with logs; Anchor prints constraint name and account index.
Does Anchor work on Agave 4.1.1?
Yes. This stack targets Agave validators with Solana CLI 3.0.10.
What should I read next in this section?
See sibling articles linked in Related for deeper anchor vs native topics.
Related
- Native Program Basics - entrypoint model
- Interacting with Native/Pinocchio Programs - mixed systems
- CU & Size Optimization - overhead tuning
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.