Directory Listing
Put a folder on the wire so a loop can eat it one file at a time
- paths
- names
- listing
- count
ComfyUI has no native "loop over the files in this folder". You end up hand-naming inputs, pasting paths, or hardcoding a batch size and hoping. This node is the honest fix: it lists what's in a folder and hands it to the graph as lists on wires - full paths on one, bare names on another, the count beside them - so a For Loop takes one file per iteration and processes a whole folder without you typing a single filename.
Its natural partner is the WAS For Loop Open/Close pair - the node's own tooltips spell out the pattern: wire paths and count into a For Loop to open one file per iteration, and carry the matching names along so each saved render keeps the filename it was made from.
The inputs that matter
folder- which folder to read, from a dropdown. A bareinput,outputortempnames ComfyUI's own folders;plates/shot_01 [input]is a folder below one of them. Any folder you've added underpaths.allow_readinconfig.yamlappears under its own name.pattern- a glob.*is everything,*.pngonly PNGs,frame_*.pngone numbered run. Matching happens inside the folder - a drive, a leading slash or a..segment is refused, which is the pack not letting you walk the whole filesystem by accident.recursive- false lists only what sits directly in the folder; true applies the pattern at every depth.include-files,directories, orboth. A loop over images wantsfiles;directorieswalks a set of shot folders.sort- order matters more than it looks.naturalreads digit runs as numbers, soframe_2comes beforeframe_10. Plainnamesorts alphabetically and putsframe_10first.modifiedgives oldest first,sizesmallest first.reverseandlimit- flip the order, and keep only the first N once sorted. Withmodified+ reverse + limit10you get the ten newest files, which is the classic "latest render at index 0" setup.
What comes out
paths(ARRAY) - every entry's full path, in order, for Text List Get / Slice / Length or a loop.names(ARRAY) - the same entries named below the folder, in the same order, so entry 3 here belongs to path 3. Wirenamesinto an Image Save's filename prefix and results keep their original names through the whole round trip.listing(STRING) - names one per line, for a preview or for re-cutting with Text Split to List.count(INT) - the length of both lists. Feed it to a For Loop's iterations and you walk the entire directory.
Installing it and the gotchas
Standard WAS Node Suite v3 install: ComfyUI Manager → search WAS Node Suite v3, or clone into custom_nodes. No weights, no extra dependencies.
Three failure modes worth knowing before you hit them. A folder that isn't there stops the prompt - loudly, on purpose, because silently listing nothing would be worse. A folder that's there but holds nothing the pattern matches answers empty lists and a count of 0, which is the silent case to guard against in a loop. And names starting with a dot are only matched by a pattern that starts with one, so *.png won't touch your hidden .png cache files - usually a feature.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| folder | COMBO | Which folder to read. A bare 'input', 'output' or 'temp' is that folder itself; 'plates/shot_01 [input]' is that folder below it. Any folder added under paths.allow_read in config.yaml is listed under its own name, and so are the folders inside it. | |
| pattern | STRING | * | Which entries to list, as a glob. `*` takes everything, `*.png` only PNGs, `frame_*.png` one numbered run. A name starting with a dot is matched only by a pattern starting with one. Matching is inside the folder: a drive, a leading slash or a '..' segment is refused. |
| recursive | BOOLEAN | false | Whether subfolders are listed too. false lists only what sits directly in the folder; true applies the pattern at every depth, so `*.png` also finds 'shot_a/frame_0.png', and every name below the top carries its subfolder. |
| include | COMBO | files | What is listed. `files` = files alone, which is what a loop over images wants; `directories` = folders alone, for walking a set of shot folders; `both` = the two together in one order. |
| sort | COMBO | natural | The order entries come out in. `name` = plain alphabetical, where frame_10 lands before frame_2; `natural` = digits read as numbers, so frame_2 comes first; `modified` = oldest first; `size` = smallest first. |
| reverse | BOOLEAN | false | Whether the order is flipped. Off, `modified` gives oldest first and `size` smallest first; on, newest first and largest first, which is how the most recent render is put at index 0. |
| limit | INT | 00–1000000 | How many entries to keep once they are sorted. 0 = every one; 1 = the first alone; 50 = the first fifty. With sort on `modified` and reverse on, 10 keeps the ten newest files. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| paths | ARRAY | Every entry's full path on one wire, in the chosen order, for Text List Get, Text List Slice and Text List Length. Wire it and count into a For Loop to open one file per iteration. |
| names | ARRAY | The same entries named below the folder, as 'frame_0.png' or 'shot_a/frame_0.png', in the same order. Entry 3 here belongs to path 3, so a saved render can carry the name it was made from. |
| listing | STRING | The names, one per line, for reading on a text preview or cutting up again with Text Split to List. Empty when nothing matched. |
| count | INT | How many entries the listing holds, which is the length of both lists. Feed it to a For Loop's iterations to walk every one. |