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
## 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.
## License
[Apache 2.0](LICENSE)