Scaffolding a CRUD resource

⏱ 6 min · 🎯 you'll have: a complete Post resource with create/read/update/delete instructions, events, errors, and TS test.

The CRUD recipe is the fastest way to add a new resource to an existing program. It composes the primitive scaffolders (account, instruction, event, error) into a coherent slice.

Pre-requisites

  • A workspace already created with sunscreen chain new.
  • At least one program in programs/.

Run

sunscreen scaffold crud Post --program my_app

Output (truncated):

✓ scaffolded account: Post
✓ scaffolded instructions: create_post, read_post, update_post, delete_post
✓ scaffolded events: PostCreated, PostUpdated, PostDeleted
✓ scaffolded errors: PostNotFound, PostUnauthorized
✓ tests/post.spec.ts

What was generated

FilePurpose
programs/my_app/src/state/post.rsPost account struct with #[account]
programs/my_app/src/instructions/create_post.rscreate_post handler
programs/my_app/src/instructions/read_post.rsread_post handler
programs/my_app/src/instructions/update_post.rsupdate_post handler
programs/my_app/src/instructions/delete_post.rsdelete_post handler
programs/my_app/src/events.rs (patched)PostCreated, PostUpdated, PostDeleted events
programs/my_app/src/errors.rs (patched)PostNotFound, PostUnauthorized variants
tests/post.spec.tsTypeScript test scaffolding the four ops

All writes happen inside marker regions. Hand-edit anywhere outside the markers and your changes survive future scaffolds.

Options

sunscreen scaffold crud Post \
  --program my_app \
  --fields "title:string,body:string,author:pubkey,created_at:i64" \
  --frontend-hook \
  --json
FlagDefaultWhat it does
--program <name>requiredprogram to scaffold into
--fields "<spec>"title:string,body:stringcomma-separated name:type pairs for the account struct
--frontend-hookoffalso generate React Query hooks (requires frontend: react in sunscreen.yml)
--dry-runoffprint what would change without writing
--jsonoffmachine-readable summary
--forceoffoverwrite existing conflicting symbols

Idempotency

Re-running the same command is a no-op:

sunscreen scaffold crud Post --program my_app
# error: account "Post" already exists in program "my_app" (exit 4)

Add --force if you really want to regenerate (will not clobber hand-edits outside markers).

What "fields" supports

Spec syntaxAnchor type
name:stringString
name:boolbool
name:u64 (also u8, u16, u32, u128)matching unsigned int
name:i64 (also i8, i16, i32, i128)matching signed int
name:pubkeyPubkey
name:vec<u8>Vec<u8> (limited to 256 bytes)

Complex types (nested structs, large vectors) need manual editing.

Build and test

sunscreen chain build
anchor test

The generated tests/post.spec.ts exercises each of the four operations end-to-end against a local validator.

Going further