layoutd
Off-chain CLI for the Solana/Anchor ecosystem that diffs account struct layouts and classifies every field change as Safe, Review, or Danger before you ship a migration.
layoutd diff old.json new.json --account Vault
layoutd check old.json new.json --account Vault # exits 1 on Danger → blocks CI
layoutd gen old.json new.json --account Vault # emits a Rust migration scaffold
Install
Or install the latest from GitHub without publishing:
What it does
Anchor encodes accounts with Borsh (sequential field encoding). If you change a struct definition in a way that shifts byte offsets for existing data, every account already on-chain becomes unreadable. layoutd catches those mistakes in CI before they hit mainnet.
Safety classification
| Change | Borsh | Zero-copy (repr(C)) |
|---|---|---|
| Field added at end | Safe | Safe |
| Field renamed (same type, same position) | Safe | Safe |
| Field type widened (u32 → u64) | Review | Danger |
| Field removed | Danger | Danger |
| Field reordered | Safe* | Danger |
| Field inserted in the middle | Danger | Danger |
* Borsh is position-independent for deserialization; reorder only matters for on-chain size.
Usage
diff — inspect changes
Accepts Anchor IDL JSON or a Rust source file (.rs):
check — CI gate
# exits 0 → all changes safe
# exits 1 → at least one Danger (blocks CI)
Output a SARIF file for GitHub PR annotations:
gen — migration scaffold
Emits a Rust impl Migration block with a migrate() function, pre-filled for every detected change, plus a // Size: comment telling you whether you need realloc().
Flags
| Flag | Description |
|---|---|
--zero-copy |
Analyse as a repr(C) zero-copy account (stricter rules) |
--ack <file> |
JSON file of explicitly acknowledged Danger changes (lets them pass CI) |
--hints <file> |
JSON file of explicit rename pairs (for cross-position renames auto-detection misses) |
--sarif <file> |
Write a SARIF 2.1.0 report (used by GitHub Code Scanning) |
Acknowledgement file (--ack)
Hints file (--hints)
Use when a field is renamed and moved to a different position simultaneously (auto-detection requires same position):
GitHub Action
- name: Check Vault layout
uses: Rudraprajapati2612/layoutd-cli@v0.1.0
with:
old-idl: old_idl.json
new-idl: idl.json
account: Vault
sarif-output: layoutd.sarif
zero-copy: 'false' # optional
ack-file: layoutd.ack # optional
hints-file: hints.json # optional
Crates
| Crate | Description |
|---|---|
layoutd |
CLI binary (cargo install layoutd) |
layoutd-core |
Core library (diff engine, classifier, SARIF emitter) |
License
Licensed under either of MIT or Apache-2.0 at your option.