Essential Crates
Shipping on Solana means assembling a stack of crates and libraries, not memorizing one framework. On-chain programs, off-chain clients, serialization, digital assets, and test harnesses each own a layer. Once you see which layer a dependency belongs to, Cargo and npm graphs stop looking like noise and start looking like a deliberate map you can pin to Agave 4.1.1, Anchor 0.32.1, Rust 1.91.1, and @solana/kit 7.0.0.
Deep dives in this section zoom into pairs and stacks: solana-program & solana-sdk, anchor-lang & anchor-spl, borsh & bytemuck, pinocchio & steel, mpl-core & mpl-token-metadata, @solana/kit, Codama & gill, and litesvm, mollusk & solana-bankrun. This page sits underneath: how the pieces fit, when each layer is justified, and how teams avoid mixing generations across a monorepo.
Summary
- Essential Solana libraries are a layered dependency map - platform program/SDK crates, optional frameworks (Anchor or Pinocchio/Steel), serialization, SPL/MPL product crates, TypeScript clients (kit/Codama/gill), and test harnesses - and each layer solves a different problem.
- Insight: Wrong layer choices cause sBPF build failures, CU bloat, IDL drift, mainnet encode bugs, and slow CI; a clear map lets you pick default product stacks, CU-critical native paths, and matching tests without cargo-culting every crate into every binary.
- Key Concepts: solana-program vs solana-sdk, Anchor 0.32.1, Pinocchio/Steel, Borsh vs bytemuck, SPL and Metaplex, @solana/kit / Codama / gill, LiteSVM / Mollusk / Bankrun, version alignment.
- When to Use: Bootstrapping a monorepo, choosing native vs Anchor vs lightweight frameworks, designing client codegen, standardizing test harnesses, or reviewing dependency hygiene before a mainnet upgrade.
- Limitations/Trade-offs: More layers mean more pins and audit surface; frameworks trade CU and ELF size for velocity; zero-copy and lightweight stacks demand stricter validation discipline; test harnesses differ in fidelity from full validators.
- Related Topics: anchor-lang/spl, borsh/bytemuck, pinocchio/steel, Metaplex crates, kit/Codama/gill, LiteSVM/Mollusk/Bankrun, library best practices.
Foundations
Solana development is multi-target by design. On-chain crates compile to sBPF with cargo build-sbf under Solana CLI 3.0.10 platform tools. Off-chain Rust and TypeScript talk to RPC, sign transactions, and decode accounts. Serialization defines how instruction and account bytes are laid out. Product asset crates (SPL Token, Metaplex) wrap widely deployed programs. Test harnesses approximate runtime behavior without always spinning a full validator.
Treat the ecosystem as layers from the loader up to the app, not as one flat Cargo.toml wishlist:
+----------------------------------------------+
| App / bot / dApp product logic |
+----------------------------------------------+
| TS clients: @solana/kit, Codama, gill | <- off-chain JS/TS
+----------------------------------------------+
| Product assets: SPL Token, MPL Core/TM | <- CPI + layouts
+----------------------------------------------+
| Framework: anchor-lang / anchor-spl |
| or pinocchio / steel | <- optional
+----------------------------------------------+
| Encoding: borsh, bytemuck (zero-copy) |
+----------------------------------------------+
| Platform: solana-program (on-chain) |
| solana-sdk + client (off-chain) |
+----------------------------------------------+
| Tests: LiteSVM, Mollusk, Bankrun | <- parallel track
+----------------------------------------------+Platform crates are non-negotiable. solana-program is the on-chain standard library (AccountInfo, entrypoints, CPI, sysvars, program errors). solana-sdk and related client crates power host binaries that build, sign, and send transactions. Keep solana-sdk out of program crates; kit never substitutes for the sBPF path.
Framework crates sit above the platform. anchor-lang 0.32.1 supplies macros, constraints, and IDL; anchor-spl adds typed SPL CPIs. That is the default product path. Pinocchio and Steel are lightweight native options when ELF size and CU matter more than Anchor ergonomics.
Serialization is orthogonal to framework choice. Borsh is the flexible default (including most Anchor layouts). bytemuck enables zero-copy POD casts when you control alignment, padding, and validation. Wrong choice shows up as CU spikes or unsafe casts without checks.
Product crates (spl-token, ATA helpers, mpl-token-metadata, mpl-core) wrap known deployed programs for assets and CPIs. They are not a second runtime. Pick Token Metadata vs Core by product model.
Client stack for greenfield TypeScript: @solana/kit 7.0.0 for RPC, codecs, and messages; Codama for kit-native clients from Anchor IDL; gill as optional sugar. Avoid new apps on @solana/web3.js v1.
Test crates close the loop: LiteSVM for fast Rust in-process tests, Mollusk for instruction/ELF fixtures, solana-bankrun for TypeScript integration. Full solana-test-validator remains the smoke option.
Mechanics & Interactions
Platform first: program vs SDK
Every program binary depends on platform types. Native and many Pinocchio paths import solana-program (or compatible re-exports). Anchor re-exports many primitives so product code rarely imports them directly, but audits and CU work still require platform literacy.
Off-chain Rust CLIs and harnesses use solana-sdk (Pubkey, Instruction, Transaction, signers) with RPC clients. TypeScript dApps use kit instead, but the roles match: compose instructions, attach accounts, sign, submit, confirm.
On-chain binary Off-chain binary / dApp
----------------- -----------------------
solana-program solana-sdk OR @solana/kit
(+ Anchor or Pinocchio) (+ Codama / gill / solders)
| |
v v
sBPF .so deploy RPC send + decodeChoosing a program framework layer
| Path | Primary crates | You gain | You pay | Best fit |
|---|---|---|---|---|
| Anchor | anchor-lang, anchor-spl 0.32.1 | Constraints, IDL, ecosystem clients | Framework size, version coupling | Most product programs + web UI |
| Native platform | solana-program | Full control, fewer macros | Hand validation, hand clients | Learning, specialized loaders |
| Pinocchio / Steel | pinocchio, Steel stack | Smaller ELF, lower CU | Less IDL/default tooling | CU-critical, size-sensitive programs |
Anchor is the default when you want IDL-driven clients and standard validation. Pinocchio/Steel fit measured CU, binary size, or audit preference against macros. Mixing frameworks across programs in a monorepo is fine; mixing them inside one binary without a boundary usually is not.
Serialization: Borsh vs bytemuck
Instruction data and account state are bytes. Borsh is the deterministic default for most args and accounts (including Anchor). bytemuck reinterprets POD account memory for hot paths when layouts are validated.
Flexible / evolving state --> Borsh (serialize / deserialize)
Fixed POD, CU-sensitive --> bytemuck (+ strict init and size checks)
Anchor zero_copy paths --> bytemuck-style layouts under framework rulesPrefer Borsh for args and evolving state; reserve zero-copy for large hot accounts. Never cast untrusted data without owner, size, discriminator, and alignment checks.
SPL and Metaplex as product layers
Token balances, ATAs, and digital assets live in deployed programs. Your code depends on builders and layouts (spl-token, ATA helpers, mpl-token-metadata, mpl-core), often via anchor-spl or kit-side helpers.
Use Token Metadata for classic mint-attached metadata and marketplace conventions. Use MPL Core when the Core model and plugins fit issuance better. Pin crates to the program revision and layout you deploy against.
Clients: kit, Codama, gill
With Anchor, anchor build emits IDL; Codama renders kit-oriented builders and decoders. kit 7.0.0 owns RPC, messages, and signers. gill shortens common kit patterns but does not replace program-specific Codama output.
anchor build --> target/idl/*.json --> Codama render
|
v
kit assembly (+ optional gill)Brownfield apps may keep Anchor's classic TS Program API; greenfield kit apps should prefer Codama + kit. One app, one primary transaction story.
Tests: LiteSVM, Mollusk, Bankrun
| Harness | Language | Strength | Gap |
|---|---|---|---|
| LiteSVM | Rust | Fast in-process SVM tests | Not a full multi-validator cluster |
| Mollusk | Rust | Instruction/ELF fixtures, CU focus | Narrower than full app flows |
| Bankrun | TypeScript | Validator-like TS integration | Heavier than pure unit tests |
| test-validator | CLI | Full local cluster smoke | Slowest CI path |
Use LiteSVM or Mollusk for program crates and Bankrun or validator smoke for client packages. Align harnesses with Agave semantics so CI does not greenlight behavior mainnet rejects.
How the layers interact in one product
- Pin Rust 1.91.1, Agave 4.1.1 / CLI 3.0.10, and Anchor 0.32.1 (if used).
- Choose framework layer per program binary (Anchor default, Pinocchio when measured need exists).
- Encode state with Borsh unless a profiled hot path needs bytemuck/zero-copy.
- CPI into SPL/MPL with version-matched crates and correct program IDs per cluster.
- Generate clients from IDL via Codama into kit 7.0.0; use gill only as sugar.
- Test with LiteSVM/Mollusk in Rust and Bankrun or validator smoke for TS paths.
- Gate releases with audits,
cargo treehygiene, and verifiable builds where trust requires it.
Advanced Considerations & Applications
Stack recipes by product shape
| Recipe | On-chain | Client | Tests | Notes |
|---|---|---|---|---|
| Default product dApp | Anchor 0.32.1 + anchor-spl + Borsh | Codama + kit 7.0.0 (+ gill optional) | LiteSVM + Bankrun or validator smoke | Fastest path for most teams |
| CU-critical program | Pinocchio/Steel + careful Borsh/bytemuck | Hand codecs or Shank/IDL story you own | Mollusk + LiteSVM, CU budgets in CI | Document why Anchor was skipped |
| NFT / digital asset app | Anchor or native + mpl-core or token-metadata | kit + Metaplex/DAS helpers as needed | Fixture accounts for metadata/Core | Match DAS provider to read path |
| Native learning / tooling | solana-program only | solana-sdk CLI or kit scripts | LiteSVM first | Builds intuition under Anchor |
| Mixed monorepo | Anchor program A, Pinocchio program B | Shared kit app with per-program Codama | Per-binary harnesses | One framework per binary, shared pins |
Version alignment and supply chain
Crates that compile together can still be wrong if they span SDK generations. Pin solana-program / solana-sdk to the Agave channel, keep anchor-lang and Anchor CLI at 0.32.1, pin kit 7.0.0 monorepo-wide, and regenerate Codama clients when IDL changes. Prefer Anza, Anchor, and Metaplex reference crates; run cargo audit / cargo deny / npm audit. Skip wrappers that only re-export three lines of kit or solana-program. Verifiable builds prove the artifact; dependency review is separate. Checklist: Essential Libraries Best Practices.
Common Misconceptions
- "I need every essential crate in every program." Layers are optional; programs need platform + encoding + chosen framework, not Metaplex and Bankrun inside the same sBPF crate.
- "anchor-lang replaces solana-program." Anchor builds on platform primitives; audits and CU work still need that literacy.
- "solana-sdk belongs in on-chain Cargo.toml." Use
solana-program(or framework re-exports) on-chain; sdk is for host binaries. - "Pinocchio is always faster, so always use it." Measure; many products are validation- and product-speed bound, not framework-overhead bound.
- "Borsh is obsolete if bytemuck exists." Borsh is still the flexible default; zero-copy is a targeted optimization.
- "kit replaces Anchor." kit is off-chain TypeScript; it does not compile programs or replace
anchor-lang. - "Codama and gill are interchangeable." Codama generates program clients from IDL; gill is optional kit sugar, not your ABI.
- "LiteSVM means I never need a validator." In-process harnesses miss some integration and RPC-only failures; keep release smoke coverage.
- "Matching major versions is enough." Anchor CLI and crates must share a line; Agave, platform tools, and SDK crates must share a generation.
FAQs
What is the single most important idea in the essential crates map?
Treat libraries as layers (platform, framework, encoding, assets, clients, tests) and only pull crates that serve the layer each binary actually owns.
When do I use solana-program vs solana-sdk?
solana-program for on-chain sBPF programs; solana-sdk (and related client crates) for off-chain Rust that builds and signs transactions.
Is Anchor required to ship a program?
No. Native solana-program or Pinocchio/Steel programs are valid. Anchor 0.32.1 is the common product default because of constraints, IDL, and client ecosystem.
When should I choose Pinocchio or Steel over Anchor?
When measured CU, binary size, or framework surface constraints dominate, and your team can own validation, layout docs, and client generation without Anchor defaults.
How do borsh and bytemuck fit with Anchor?
Borsh is the usual instruction and account encoding path; Anchor zero-copy account patterns use bytemuck-style POD layouts under framework rules for hot accounts.
Do I need both mpl-core and mpl-token-metadata?
Usually not. Pick Core or classic Token Metadata based on asset model and marketplace requirements; many apps standardize on one primary standard.
Where does @solana/kit sit relative to on-chain crates?
Entirely off-chain. Kit 7.0.0 handles RPC, codecs, and transactions in TypeScript; program compile remains Rust plus cargo build-sbf (and often Anchor).
What is Codama for if I already have an IDL?
Codama turns Anchor IDL into typed kit-native builders and decoders so frontends do not hand-pack discriminators and account metas.
Is gill mandatory with kit?
No. Use kit alone with Codama-generated program clients if you prefer; gill is optional sugar.
LiteSVM vs Mollusk vs Bankrun: which one first?
Start with LiteSVM for Rust program tests; add Mollusk for instruction/ELF cases; use Bankrun or test-validator when TypeScript integration fidelity matters.
Can one monorepo mix Anchor and Pinocchio programs?
Yes across different program binaries. Document the choice per program and keep shared Agave, Rust, and client pins aligned.
What should I pin for this site's stack?
Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, Rust 1.91.1, and @solana/kit 7.0.0, with program SDK crates from the same Agave generation.
How does this map relate to the toolchain blueprint?
Toolchain covers binaries and install paths (agave-install, avm, cargo build-sbf). This page covers library dependencies you declare once those tools are installed.
Related
- anchor-lang & anchor-spl - framework crates, IDL, and SPL CPI helpers
- borsh & bytemuck - serialization defaults and zero-copy paths
- litesvm, mollusk & solana-bankrun - program and client test harnesses
- mpl-core & mpl-token-metadata - Metaplex digital asset crates
- pinocchio & steel - lightweight native program frameworks
- @solana/kit, Codama & gill (JS/TS) - modern TypeScript client stack
Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, Rust 1.91.1, and @solana/kit 7.0.0.