CRUD recipe

sunscreen scaffold crud <NAME> --program <PROGRAM> [FLAGS]

Flags

FlagDefaultDescription
--program <name>requiredwhich program to scaffold into
--fields <spec>title:string,body:stringaccount fields
--frontend-hookoffalso generate matching React/Solid hooks
--dry-runoffprint plan only
--jsonoffmachine-readable summary
--forceoffoverwrite marker content even if a symbol exists

Field types

--fields accepts comma-separated name:type pairs:

SpecAnchor typeNotes
name:stringStringUTF-8, max 256 bytes by default
name:boolbool
name:u8name:u128u8u128
name:i8name:i128i8i128
name:pubkeyPubkey
name:vec<u8>Vec<u8>max 256 bytes
name:option<u64>Option<u64>optional fields

Types outside this set require hand-editing the generated account.

Generated files

For scaffold crud Post --program blog:

PathStatus
programs/blog/src/state/post.rscreated
programs/blog/src/state/mod.rspatched (marker)
programs/blog/src/instructions/create_post.rscreated
programs/blog/src/instructions/read_post.rscreated
programs/blog/src/instructions/update_post.rscreated
programs/blog/src/instructions/delete_post.rscreated
programs/blog/src/instructions/mod.rspatched
programs/blog/src/lib.rspatched (dispatch markers)
programs/blog/src/events.rspatched (3 new variants)
programs/blog/src/errors.rspatched (2 new variants)
tests/post.spec.tscreated

Generated instructions

InstructionAccountsEffect
create_post[authority: Signer, post: Account<Post> (init), system_program]initializes a Post PDA seeded by authority + name
read_post[post: Account<Post>]view-only; emits PostRead if the read fee model is enabled (off by default)
update_post[authority: Signer, post: Account<Post> (mut, has_one = authority)]updates fields, emits PostUpdated
delete_post[authority: Signer, post: Account<Post> (close = authority, has_one = authority)]closes the account, emits PostDeleted

PDA seeds: ["post", authority.key, name.as_bytes()].

Generated events

  • PostCreated { post: Pubkey, author: Pubkey, timestamp: i64 }
  • PostUpdated { post: Pubkey, timestamp: i64 }
  • PostDeleted { post: Pubkey, timestamp: i64 }

Generated errors

  • PostNotFound — account discriminator mismatch.
  • PostUnauthorized — signer is not the authority on the account.

Frontend hook (--frontend-hook)

For React + React Query:

useCreatePost({ authority, name, fields });
useReadPost({ post });
useUpdatePost({ authority, post, fields });
useDeletePost({ authority, post });

Hooks invalidate the relevant queries on mutation success. Generated in app/src/hooks/post.ts.

Exit codes

CodeWhen
0success
4preflight conflict (symbol already exists; pass --force to overwrite marker content)
5not in a workspace