no_std & the Program Environment
Solana programs compile to SBF and run in a sandbox without std. You get solana_program syscalls, optional alloc, and a strict CU budget.
Recipe
#![no_std]
extern crate alloc;
use solana_program::{
account_info::AccountInfo, entrypoint, program_error::ProgramError,
pubkey::Pubkey,
};When to reach for this:
- Starting any native (non-Anchor) program crate.
- Auditing why a dependency fails to build for
cargo build-sbf. - Choosing between
alloccollections and fixed-size account layouts.
Working Example
#![no_std]
extern crate alloc;
use alloc::vec::Vec;
use solana_program::{
account_info::AccountInfo, entrypoint, entrypoint::ProgramResult,
program_error::ProgramError, pubkey::Pubkey,
};
entrypoint!(process_instruction);
pub fn process_instruction(
_program_id: &Pubkey,
accounts: &[AccountInfo],
instruction_data: &[u8],
) -> ProgramResult {
if instruction_data.is_empty() {
return Err(ProgramError::InvalidInstructionData);
}
let _owner = accounts.get(0).ok_or(ProgramError::NotEnoughAccountKeys)?;
let buf: Vec<u8> = instruction_data.to_vec();
solana_program::msg!("bytes: {}", buf.len());
Ok(())
}What this demonstrates:
#![no_std]plusextern crate allocis the default native program layout.- Instruction data arrives as a byte slice - copy only when mutation is required.
- Account access goes through
AccountInforeferences supplied by the runtime.
Deep Dive
How It Works
- The Agave 4.1.1 runtime loads your
.soand invokes the symbol registered byentrypoint!. - Syscalls (logging, CPI, account borrow) are the only way to interact with chain state.
- Panics abort the instruction; there is no unwinding across the host boundary.
Available Crates
| Layer | Examples | Notes |
|---|---|---|
| Core | solana_program | Accounts, CPI, sysvars, errors |
| Serialize | borsh, bytemuck | Instruction and account layouts |
| Math | num-traits, checked ops | Avoid std math |
| Avoid | std, tokio, reqwest | Will not compile for SBF |
Rust Notes
// Prefer &[u8] over Vec unless you must own bytes.
// solana_program re-exports Pubkey, ProgramError, and sysvars.Gotchas
- Importing std - Adding a crate that pulls
stdbreakscargo build-sbf.. Fix: Pin deps withcargo treeand preferno_std-compatible crates. - Heap churn -
Vec::pushin hot paths allocates and costs CUs.. Fix: Use fixed account sizes or stack arrays with known bounds. - Panic on parse -
unwrapon bad client data aborts the whole transaction.. Fix: ReturnProgramError::InvalidAccountDatainstead. - Missing alloc - Using
Vecwithoutextern crate allocfails to link.. Fix: Addextern crate allocat crate root. - Debug prints -
println!is unavailable on-chain.. Fix: Usemsg!or custom errors sparingly.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| Anchor 0.32.1 | Faster iteration with account macros | Maximum CU/binary efficiency |
| Pinocchio | Zero-dependency entrypoints | Need Anchor ergonomics |
| bytemuck only | Large fixed layouts | Variable-length strings |
FAQs
Can I use std collections on-chain?
No std. Use alloc (Vec, String) or store data in accounts.
What happens on panic?
The instruction fails and no state changes commit.
How do I print debug info?
Use msg! - it costs CUs and appears in transaction logs.
Is threading available?
No. Single-threaded execution per instruction.
Can programs read the filesystem?
No I/O beyond account data and syscalls.
Why `extern crate alloc`?
Enables heap allocation through the program allocator.
What is SBF?
Solana Bytecode Format - the on-chain target (successor to BPF).
How do I test no_std code?
Use #[cfg(test)] on host with solana-program-test or LiteSVM 0.6.x.
Can I use async/await?
No async runtime on-chain.
What sysvars exist?
Clock, Rent, Instructions - read via sysvar modules.
How big can the stack be?
Keep stack usage small; large state belongs in accounts.
Does `format!` work?
It allocates heavily - avoid in production paths.
Related
- Rust for Solana Basics - Section orientation
- Borsh Serialization - Data encoding
- Program Size & CU Discipline - Performance
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.