CSV to Prompt
Batch-generate from a CSV of prompts
- positive_string
- negative_string
If you've ever had to generate fifty images where only the prompt changes, you know the ritual: change text, queue, change text, queue. Boring, error-prone, and it's exactly the problem this node was written to kill. CSV to Prompt reads a spreadsheet of prompt pairs and feeds one row at a time into your workflow, so a single queue run churns through your whole list without touching a text box. It's not clever, it's not flashy - it's the "just make the batch happen" node, and that's a niche that's genuinely useful.
Author Tharinda Marasingha shipped it in late 2025 after hitting the same wall himself: he needed hundreds of images from a pre-written list, found every existing solution too fiddly, and built the minimal version. That origin shows in the code - there's almost nothing to it. The node scans a folder, picks a row by your seed, and hands you two strings. That's the whole contract.
How it works
The mechanism is deliberately simple. You drop a .csv file into the csv_files folder inside the node's own directory (ComfyUI/custom_nodes/ComfyUI-CSV-to-Prompt/csv_files/). When the node is created, it scans that folder and populates a dropdown with every .csv it finds. On each run it opens your file, reads the rows with Python's standard csv module (no pandas, no model files, no dependencies - the whole pack is one file of stdlib), and picks a row like this:
row_index = seed % len(rows)
That's the entire "batch magic." Your seed is not a seed here - it's a row selector. Seed 0 gives you the first data row, seed 1 the second, wrapping back to the start when you run past the end. The trick the README teaches: set the node's seed widget to increment in its control_after_generate dropdown, set your queue's Batch count to the number of rows in the file, and hit Queue. Run 1 uses seed 0 (row 1), run 2 uses seed 1 (row 2)… done.
The inputs and outputs that matter
Only two inputs, and one of them you'll rarely touch:
csv_filename- the dropdown of.csvfiles found incsv_files. Pick yours.seed- an INT, default 0. It selects the row, viaseed % row_count. Unless you want to skip ahead or start mid-list, just leave it on the default and let increment do the work.
Both outputs are plain strings, and they wire straight into your existing CLIP Text Encode nodes:
positive_string→ your CLIP Text Encode (Positive) text inputnegative_string→ your CLIP Text Encode (Negative) text input
Your CSV needs headers - the code looks for columns literally named positive and negative. Extra columns (the sample file even has a Number column) are ignored, and the author's code is forgiving enough to also catch the typo negetive as a negative header. Rows are pulled in order and fed to the encoders as-is; if a cell is empty, the encoder gets an empty string and you'll burn a run on garbage.
Installing it
ComfyUI Manager is the easy route: Install via Git URL and paste https://github.com/TharindaMarasingha/ComfyUI-CSV-to-Prompt. Or, manually:
cd ComfyUI/custom_nodes/
git clone https://github.com/TharindaMarasingha/ComfyUI-CSV-to-Prompt
Then restart ComfyUI. There are no heavy dependencies to install and no model files to download - the pack is pure Python stdlib.
Where people get burned
- The dropdown is baked at node creation. If you add a
.csvafter creating the node, it won't show up until you refresh the frontend or re-add the node. Drop the file in first, then place the node. If no file is found, the dropdown shows aPut_CSV_in_csv_files_folder.csvplaceholder and every row returns "Error". - The off-by-one will confuse you once. The README says "Seed 1 loads Row 1," but the code says seed 0 = first row. It doesn't matter for batch mode (increment from 0 covers everything), but if you're manually dialing in a specific row, remember seed 2 is the third row, not the second.
- Encoding is hardcoded to UTF-8. A spreadsheet saved as latin-1, or with a UTF-8 BOM, can silently break the header match so
positiveisn't found. Save as plain UTF-8. - The negative prompt only does something on models that use one. This node just feeds strings; on the newer LLM-encoded, guidance-distilled models the negative box is largely inert. It's perfect for SD 1.5/SDXL-lineage checkpoints, where negatives still earn their keep.
- "Prompt has no outputs" isn't a bug in this node - it means your workflow is missing a Save Image or Preview Image at the end, so nothing identifies the run as worth executing.
It's a one-trick pony, and that's fine. If you batch-generate from a list, this is the fastest way to wire it up without adopting a whole prompt-alternator suite - and at this size, there's not much to go wrong.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| csv_filename | COMBO | 1 options: Sample_Prompt_file.csv | |
| seed | INT | 00–18446744073709550000 | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| positive_string | STRING | — |
| negative_string | STRING | — |