Turn a shadcncraft Figma node into React + shadcn/ui code that drops into the project clean, on the project's tokens, icons, and conventions. The headline idea: the kit and the registry are the same library, so most frames already exist as a hand-tuned registry block. Reuse beats regeneration.
-
License gate (check first, fail fast). generate-code is a Pro React or Pro Figma + React feature: it installs shadcncraft React pro blocks, and the registry serves those only to a valid license key from either React-shipping product. Before doing any work, check for a SHADCNCRAFT_LICENSE_KEY in the project's environment. If it is missing, stop and tell the user this, in a friendly way: generate-code requires a Pro React or Pro Figma + React license; they can get or upgrade at https://shadcncraft.com/pricing (existing customers: https://shadcncraft.com/upgrade), then set SHADCNCRAFT_LICENSE_KEY and re-run. Do not push ahead and silently produce a generic, un-themed approximation as a "free" fallback, which misrepresents the kit. (Token-only work with no pro blocks is shadcncraft-import-variables, which is free for everyone.)
-
Preflight the project. Generated code only looks right if the project is set up for shadcncraft: the @shadcncraft registry configured, a license key for pro blocks, and fonts wired up (missing fonts is why output comes out serif). If any of that is missing, set it up first. See references/project-setup.md. Skipping this is the number-one reason a result looks nothing like the design.
-
Get the node. From the user's selection or pasted link, get the node ID and a screenshot. Use get_metadata for the node ID (12345-67890 form) and get_screenshot to see it. Use get_design_context for structure when you need it.
-
Whole page? If the selection is a full page (its direct children are several … - Pro <Bundle> Block instances), do not treat it as one component. Resolve every section to its registry block, batch-install them, then for each section copy the block into a page-scoped file and adapt the copy to the frame: real copy and real images via get_design_context (each <img> comes back as one flattened asset URL, and download_assets returns sub-fills for composed panels, not the panel image), and the layout deltas the frame shows (hidden="true" parts removed, restyled surfaces), before composing. Don't edit the installed block in place. The metadata layer names are component defaults, not the instance's real text, and installing a block ships its default stock image, not the design's, so blocks left as-installed read "Acme Inc." with the kit's generic art and the page looks nothing like the frame. See references/full-page-frames.md.
-
Otherwise, reuse before you generate. Resolve the single frame to a registry item by its data-slot value or frame name in references/registry-index.json (mind the -1 variant suffix; node IDs are NOT a reliable key, see component-mapping.md). If it matches, install it instead of writing JSX:
npx shadcn@latest add @shadcncraft/<name>
If the name maps to several variants, disambiguate by screenshot + title. This is rule 0; do not skip it. Write the command in the project's package manager (pnpm/yarn/bun/npm), and for a pro-* bundle item remind the user to set SHADCNCRAFT_LICENSE_KEY (see component-mapping.md). Then, if the frame differs from the block (copy, images, or layout, almost always for a real design), copy it into a page-scoped file and adapt the copy to the frame rather than editing the installed block in place.
-
Read components.json for style, iconLibrary, and aliases. These drive everything downstream.
-
Generate (only when there is no registry match). Compose from shadcn/ui primitives and shadcncraft components, following the reference files below. Do not hand-roll what a primitive already provides.
-
Self-review and return. Run the checklist in references/output-conventions.md. Return the file(s) with paths, any add commands for dependencies (in the project's package manager; with the SHADCNCRAFT_LICENSE_KEY reminder for pro items), and a short note of assumptions made.