Instruction Data (de)Serialization
Instruction data is the contract between clients and your program. Borsh enums are standard; manual opcodes work for tight control. Both require stable versioning discipline.
Search across all documentation pages
Instruction data is the contract between clients and your program. Borsh enums are standard; manual opcodes work for tight control. Both require stable versioning discipline.
#[derive(BorshSerialize, BorshDeserialize)]
pub enum MarketInstruction {
PlaceOrder { price: u64, qty: u64 },
}When to reach for this:
#[derive(BorshSerialize, BorshDeserialize)]
pub enum MarketInstruction {
PlaceOrder { price: u64, qty: u64 },
CancelOrder { order_id: u64 },
}
pub fn parse(data: &[u8]) -> Result<MarketInstruction, ProgramError> {
MarketInstruction::deserialize(&mut &data[..]).map_err(|_| ProgramError::InvalidInstructionData)
}What this demonstrates:
version: u8 before body for breaking changes.Publish a instructions crate shared by program and TS/Rust clients.
let data = ix.try_to_vec()?; // off-chain builder#[repr(C)] with care.| Alternative | Use When | Don't Use When |
|---|---|---|
| Shared crate + Codama | IDL-driven clients | Quick scripts |
Anchor #[program] | Auto serialization | Custom layouts |
| Raw byte slices | Single-field ix | Complex enums |
Transaction packet limits - keep ix small.
For <256 variants yes.
Supported - document endianness.
32 bytes in Borsh.
Use Option<T> in Borsh.
Only if single instruction program.
Use for upgrade audits.
Recommended in CI.
Returns parse error.
Different encoding if mixing - avoid.
Off-chain only; on-chain binary.
Check in hex fixtures.
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