declare_program!
Anchor 0.32.1 declare_program! macro generates Rust modules for external programs: instruction builders, account types, and CPI helpers from IDL JSON.
Recipe
declare_program!(other_program);
other_program::cpi::initialize(
CpiContext::new(
ctx.accounts.other_program.to_account_info(),
other_program::cpi::accounts::Initialize { /* ... */ },
),
)?;When to reach for this: Your program CPIs to another Anchor program with a published IDL.
Working Example
use anchor_lang::prelude::*;
declare_program!(marketplace);
#[derive(Accounts)]
pub struct ListViaMarketplace<'info> {
pub marketplace_program: Program<'info, marketplace::program::Marketplace>,
#[account(mut)]
pub listing: Signer<'info>,
}
pub fn list(ctx: Context<ListViaMarketplace>, price: u64) -> Result<()> {
marketplace::cpi::list(
CpiContext::new(
ctx.accounts.marketplace_program.to_account_info(),
marketplace::cpi::accounts::List {
listing: ctx.accounts.listing.to_account_info(),
},
),
price,
)?;
Ok(())
}What this demonstrates:
- IDL file must be on macro search path
- Generates program::Program type for validation
- cpi submodule mirrors callee instructions
- Re-run build when callee IDL updates
Deep Dive
Setup
Place marketplace.json IDL in workspace and reference in build config per Anchor 0.32 docs.
Type Safety
Generated account structs reduce CPI meta mistakes vs raw invoke.
Gotchas
- IDL version mismatch with deployed program - CPI fails at runtime.. Fix: Pin IDL git SHA to deployment.
- Missing accounts in CPI struct - Callee rejects transaction.. Fix: Match generated struct exactly.
- Wrong program id in Program<T> - Constraint failure.. Fix: Use generated program module type.
- Macro path not found - Build fails.. Fix: Configure idl path in Anchor.toml.
- Callee not Anchor - IDL may be incomplete.. Fix: Use manual CPI or compatible IDL.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| Manual invoke with discriminator bytes | Non-Anchor callees | IDL-available programs |
| Client-only composition | No on-chain CPI | Atomic program composition |
FAQs
Anchor version?
0.32.1 across advanced topics.
When to use zero_copy?
Large fixed layouts when Borsh CU too high.
Is realloc reversible?
Not easily; plan forward growth.
Are remaining accounts in IDL?
No; document separately.
declare_program! needs what?
Callee IDL JSON at compile time.
Can Anchor CPI to Pinocchio?
Yes with correct account metas.
Feature flags and IDL?
Avoid different IDL per feature on mainnet.
How to measure CU?
LiteSVM, Surfpool, devnet simulation.
Custom account types common?
No; last resort.
Next steps?
See Related links for declare_program.
Related
- CPI to Custom Programs - CPI usage
- The Anchor IDL - IDL format
- Codama from an Anchor IDL - TS codegen
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.