Node Types Reference¶
Deep dive on every node type you'll encounter in a .nbflow. Read this once and you'll understand any workflow you open in PatchWork.
How nodes work¶
A node has inputs (left side), outputs (right side), and properties (settings). You wire outputs to inputs with links (edges). Some nodes hold data (prompts, images); some nodes do work (generate images, generate video). The graph runs by walking from data nodes to work nodes to approval nodes.
flowchart LR
P[Prompt<br/>data] --> G[Generation<br/>work] --> A[Approve<br/>review]
M[Media<br/>data] --> G
The five node types¶
| Type | Category | What it does |
|---|---|---|
nanobanana/Prompt |
Data | Holds prompt text — static, template, or dynamic (multi-row) |
nanobanana/Media |
Data | Holds an image — reference upload or generated output |
nanobanana/NanobananaAPI |
Work | Generates images via the G-Labs API |
nanobanana/Veo3 |
Work | Generates video clips via Veo 3.1 |
Approve |
Review | Surfaces candidates in a gallery for the user to pick from |
Prompt node¶
nanobanana/Prompt — the most common node type. Holds prompt text in one of three modes.
Modes¶
Plain— just text. One value, one output. Wire its output to any prompt input.- Use this for single-row content that doesn't change across scenes or variants. Examples: a per-scene image composition spec, a one-off pose description.
Template— text with{placeholder}tokens. Receives values from other Prompt nodes through input slots and substitutes them into the text.- Use this when multiple variable parts need to combine into one prompt. Example: a Veo template with
{dialogue}and{pose}placeholders fed by two separate Dynamic Prompts. Dynamic— multi-row list of text values. Outputs each row in turn, fanning the downstream generation node out one run per row.- Use this when (a) you have a fan-out batch (4 dialogue lines → 4 video clips), or (b) the prompt's text gets swapped during Lvl ½ variants (typical for dialogue lines).
Key properties¶
| Property | What it does |
|---|---|
text |
The prompt text. For templates, contains {placeholder} tokens. |
templateMode |
Boolean. True = template mode (placeholder substitution). |
dynamicMode |
Boolean. True = dynamic mode (multi-row fan-out). |
dynamicRows |
Array of strings, one per row. Must be flat strings — objects cause runtime errors. |
variableName |
Short lowercase identifier (e.g. scene, dialogue, pose) that matches the placeholder in the downstream template. This is the wiring contract. |
When to use which mode¶
flowchart TD
Q[Does the prompt feed multiple rows<br/>or get fan-out?]
Q -->|YES| D1[Dynamic - multi-row]
Q -->|NO| Q2[Does the prompt's text get swapped<br/>during Lvl 1/2 variants?]
Q2 -->|YES| D2[Dynamic - 1 row, variant-swap target]
Q2 -->|NO| P1[Plain Prompt]
P1 --> Q3[Does the gen node need placeholder<br/>substitution from multiple sources?]
Q3 -->|YES| T1[Keep template, plain Prompt feeds one slot]
Q3 -->|NO| T2[Drop template, plain Prompt feeds gen directly]
Common mistake¶
Dynamic variableName must match the template placeholder
If the template references {scene}, the dynamic must have variableName: "scene". If you use the node's human-readable title there (Dynamic: Group A — Scene 01 specifics), substitution silently fails and the model receives the literal string {scene} as the prompt — generations look unrelated to what the dynamic carries.
Use short lowercase identifiers as the variableName: scene, dialogue, pose, broll, motion. The title can be human-readable, but variableName is the wiring contract.
Media node¶
nanobanana/Media — holds an image. Two roles:
Reference image- Uploaded by the user. The avatar's character reference sheet, a product photo, a setting reference. Has
mode: "reference"and animageDataURL pointing to an R2-uploaded image. Wire its output into a generation node'simage 1orimage 2slot. Cached output- Created automatically after a generation completes. Holds the public R2 URL of a generated image so downstream nodes can reuse it.
Key properties¶
| Property | What it does |
|---|---|
mode |
"reference" for uploaded refs, "output" for generation outputs. |
imageData |
Public R2 URL (e.g. https://pub-....r2.dev/...png). Can be null if a reference hasn't been uploaded yet. |
inputs |
Has 1 input slot named input with link: null. Required for shape consistency even though refs are data sources. |
When to use¶
- Avatar reference sheet (face lock across generations) — Media node with
mode: "reference", wired into the character ref slot of every image gen for that account. - Product photo — Media node wired into the second image input of any gen that needs the product visible.
- Setting / establishing image — Media node wired into the start-frame slot of a Veo3 node.
Common mistake¶
Don't generate avatar reference sheets — upload them
Avatar reference sheets are uploaded by the user, not produced by NanoBanana. Don't build a Prompt → NanobananaAPI → Approve → Media chain for the avatar reference. Just use one Media node with the user-uploaded photo.
NanobananaAPI node¶
nanobanana/NanobananaAPI — generates images via the G-Labs API. Takes a prompt and up to two reference images, returns N candidate images.
Inputs¶
| Slot | Name | What goes here |
|---|---|---|
| 0 | prompt |
The text prompt (from a Prompt node — plain, template, or dynamic). |
| 1 | image 1 |
Primary reference image (typically the avatar character sheet). |
| 2 | image 2 |
Secondary reference image (typically the product photo). |
Slot names have spaces, not underscores. image 1, not image_1. Wrong-name slots break import.
Key properties¶
| Property | What it does |
|---|---|
model |
Must be "nano_banana_2". Never leave unset — defaults to NanoBanana 1, which produces different (worse) results. |
outputCount |
Always 4. Produces 4 candidate images per run for the user to pick from. |
aspectRatio |
Usually "9:16" for vertical short-form. |
_savedImages |
After generation, holds the R2 URLs of the produced images. |
Common mistakes¶
Always set model: nano_banana_2
Every NanobananaAPI node must have "model": "nano_banana_2" in its properties. Missing this field causes G-Labs to default to the older NanoBanana 1, which is structurally different and produces worse results. Always verify before running.
outputCount defaults can drift
The default outputCount for image gens is 4 (gives the user 4 candidates to pick from). Some importers emit outputCount: 1 by accident — verify before running.
Veo3 node¶
nanobanana/Veo3 — generates a video clip via Veo 3.1. Takes a prompt, a start frame, and an optional end frame, returns N video clips.
Inputs¶
| Slot | Name | What goes here |
|---|---|---|
| 0 | prompt |
The video prompt (usually a template with {dialogue} and/or {pose} placeholders). |
| 1 | start frame |
The first frame of the video (output from an image gen, or a Media node). |
| 2 | end frame |
Optional final frame. If present, Veo interpolates start → end. If absent, Veo extrapolates motion from the start frame. |
Veo3 needs all 3 input slots present even when end-frame isn't wired. The third slot should have link: null. Missing the slot causes r.trim is not a function errors on import.
Key properties¶
| Property | What it does |
|---|---|
model |
"veo-3.1-fast-generate-preview" (or whatever the current Veo version is). |
outputCount |
Always 4. Produces 4 candidate clips per run. |
negativePrompt |
A string (can be empty). Must be a string, not undefined — otherwise crashes on .trim(). |
resolution |
Typically "1080p" or "720p". |
seed, imageCount, sampleCount, repeatCount, timeout |
Standard generation params. Importer must fill these or the node won't import cleanly. |
When to use start frame only vs start + end¶
| Situation | Start frame | End frame |
|---|---|---|
| Low-movement scene (talking head) | image gen output | same image (prevents drift) |
| Transformation clip (before → after) | "before" image | "after" image — Veo interpolates the change |
| Sequential action (per-step recipe) | step N image | usually omit; trim post-generation |
| Avatar moving to a new location | NOT ALLOWED in one clip — split into separate scenes with their own start frames |
Never prompt location changes without an end frame
Frames-to-video mode interpolates between the given frames. If you tell Veo "the avatar walks into the kitchen" but only give it a start frame in the living room, it hallucinates the transition and produces unusable footage. Location changes are new scenes, not movements within a clip.
Approve node¶
Approve / Approval — gate node. Surfaces upstream generation candidates in a gallery for the user to pick from.
What it does¶
After a generation node produces N candidates (typically 4), the Approve node downstream shows them in a grid. The user clicks the strongest take. The picked output flows downstream to whatever consumes the approval (e.g. a Veo3 node that needs an approved still as its start frame).
Properties¶
Approve nodes are mostly UI state — what's been picked, what's been rejected, gallery position. The important fields are usually managed by PatchWork automatically.
When to wire them in¶
- After every image gen (NanobananaAPI → Approve) — gives the user a pick-list of stills.
- After every video gen (Veo3 → Approve) — gives the user a pick-list of clips. This is the standard wiring.
A workflow without Approve nodes is harder to review — the user can't easily see and pick from candidates. Always include them on the user-facing review path.
Putting it together — a typical scene¶
Here's what a single speaking scene looks like as a graph:
flowchart LR
P1[Plain Prompt:<br/>scene composition JSON] --> NB[NanobananaAPI<br/>model: nano_banana_2<br/>outputCount: 4]
CR[Media: avatar ref] --> NB
PR[Media: product photo] --> NB
NB --> AP1[Approve: pick still]
D[Dynamic Prompt:<br/>dialogue 1 row] --> T[Template:<br/>universal talking head]
PO[Plain Prompt:<br/>pose / motion] --> T
T --> V[Veo3<br/>outputCount: 4]
AP1 --> V
V --> AP2[Approve: pick clip]
The Approve between the image gen and Veo3 lets the user pick the strongest still before video generation runs. The Approve after Veo3 lets the user pick the final clip.
Connection rules¶
What outputs can feed which inputs:
| From → To | Allowed |
|---|---|
| Prompt (any mode) → Prompt template slot | Yes |
Prompt (any mode) → NanobananaAPI prompt |
Yes |
Prompt (any mode) → Veo3 prompt |
Yes |
Media → NanobananaAPI image 1 or image 2 |
Yes |
Media → Veo3 start frame or end frame |
Yes |
| NanobananaAPI → Approve | Yes (standard) |
| Veo3 → Approve | Yes (standard) |
Approve → Veo3 start frame |
Yes (the picked still feeds the video gen) |
Approve → NanobananaAPI image 1 |
Rare but allowed (e.g. an approved character pose used as a ref) |
What to verify before running¶
Before triggering a generation pass on any .nbflow, walk through:
- Every NanobananaAPI has
model: "nano_banana_2". - Every NanobananaAPI and Veo3 has
outputCount: 4. - Every Veo3 has 3 input slots (
prompt,start frame,end frame) and a stringnegativePrompt. - Every Dynamic Prompt's
variableNamematches the placeholder in its template (scene,dialogue,pose, etc.). - Every link's target slot exists on the target node (no dangling links pointing to slots that were dropped).
The next page — Common Errors — covers what to do when one of these checks fails.