Building a Program with Pinocchio
A Pinocchio program combines a thin entrypoint, strict account validation, Borsh or opcode dispatch, and CPI helpers - mirroring native structure with less boilerplate overhead.
Search across all documentation pages
A Pinocchio program combines a thin entrypoint, strict account validation, Borsh or opcode dispatch, and CPI helpers - mirroring native structure with less boilerplate overhead.
entrypoint!(process_instruction);
fn process_instruction(id: &Pubkey, accounts: &[AccountInfo], data: &[u8]) -> ProgramResult {
match data.first() { Some(0) => init(id, accounts), _ => Err(ProgramError::InvalidInstructionData) }
}When to reach for this:
pub fn init(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
let [payer, state, system @ ..] = accounts else { return Err(ProgramError::NotEnoughAccountKeys) };
if !payer.is_signer() { return Err(ProgramError::MissingRequiredSignature); }
// CPI create via pinocchio invoke / system instructions
Ok(())
}What this demonstrates:
Generate with Codama for @solana/kit 7.0.0 clients.
// Centralize account validation helpers.| Alternative | Use When | Don't Use When |
|---|---|---|
| Anchor new project | Speed | CU |
| Steel framework | More sugar | Slightly heavier |
| Template repos | Bootstrap | Maintenance |
Separate programs via CPI.
Configure per docs.
Same spl helpers.
invoke_signed equivalent.
cargo build-sbf.
solana-verify.
solana program deploy.
Same loader as native.
Custom u32 codes.
Syscall log minimal.
Local deploy test.
Pin toolchain.
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.
Reviewed by Chris St. John·Last updated Jul 16, 2026