ComfyUI JSON Dynamic Loader

License ComfyUI

A single ComfyUI node that reads any JSON file and **automatically creates output slots** for every key it finds. No hardcoded outputs — when your JSON structure changes, just click Refresh. ## Features - **Auto-discovery** — reads JSON keys and exposes them as named outputs - **Type detection** — `INT`, `FLOAT`, `STRING` types with colored connectors - **Batch support** — `sequence_number` input for `batch_data` arrays - **Connection-safe refresh** — adding new keys preserves existing links - **Workflow persistence** — keys, types, and connections survive save/reload ## Installation ### ComfyUI Manager Search for **JSON Dynamic Loader** in the ComfyUI Manager registry. ### Manual ```bash cd ComfyUI/custom_nodes/ git clone https://github.com/ethanfel/ComfyUI-JSON-Dynamic.git # Restart ComfyUI ``` ## Usage 1. Add **JSON Dynamic Loader** node to your workflow 2. Enter a `json_path` and `sequence_number` 3. Click **Refresh Outputs** 4. Outputs appear named after your JSON keys with correct types 5. Connect to downstream nodes

Node diagram showing JSON Dynamic Loader connected to KSampler

## Type Handling | JSON type | Output type | Connector | |:---|:---|:---| | `42` (integer) | `INT` | Blue | | `3.14` (float) | `FLOAT` | Teal | | `"hello"` (string) | `STRING` | Pink | | `true` / `false` | `STRING` (`"true"` / `"false"`) | Pink | ## JSON Format ### Flat JSON (single segment) For simple use cases, the node reads keys directly from the root object. The `sequence_number` input is ignored. ```json { "general_prompt": "A cinematic scene...", "seed": 42, "flf": 0.5, "camera": "pan_left" } ``` ### Batch JSON (multiple segments) For multi-shot workflows, wrap entries in a `batch_data` array. Each entry is a **segment** representing one shot/scene with its own settings. The `sequence_number` input selects which segment to read. ```json { "batch_data": [ { "sequence_number": 1, "general_prompt": "Wide establishing shot of a city", "seed": 42, "camera": "static", "flf": 0.0 }, { "sequence_number": 2, "general_prompt": "Close-up of the protagonist", "seed": 108, "camera": "pan_left", "flf": 0.5, "my_custom_key": "only on this segment" }, { "sequence_number": 3, "general_prompt": "Aerial drone shot over rooftops", "seed": 77, "camera": "zoom_in", "flf": 0.8 } ] } ``` ### Segment lookup The node resolves which segment to read using this logic: 1. **Match by `sequence_number` field** — scans `batch_data` for an entry whose `sequence_number` matches the input 2. **Fallback to array index** — if no match is found, uses `sequence_number - 1` as the array index (clamped to bounds) 3. **No `batch_data`** — reads keys from the root object directly This means segments don't need to be in order and can have gaps (e.g. 1, 5, 10). Each segment can have different keys — click **Refresh Outputs** after changing `sequence_number` if the keys differ between segments.

Segment lookup diagram showing batch_data selection

## License [Apache 2.0](LICENSE)