Custom nodes with a touch of extra UX ✨ Client-side LLM chat, mid-workflow image editing, history for primitives, JSON manipulation, analytics nodes, CivitAI metadata fetching and saving... and more!
35
stars
967
commits
Python
primary language
Aug 29, 2026
updated

A suite of custom nodes for ComfyUI aimed at enhancing user experience with more interactive and visually engaging widgets.
Most UI elements used by the frontend belong to the LF Widgets webcomponents library, a modern collection of modular and customizable webcomponents built on Stencil.js specifically to integrate with LF Nodes.

The nodes span quite a few categories:
To see example workflows, check the example_workflows folder. For generic texture serialization, see DDS Output. For the current visual-novel node inputs and identity contract, see Visual Novel Nodes.
ComfyUI/custom_nodes folder.ComfyUI/custom_nodes folder.git clone https://github.com/lucafoscili/lf-nodes.git.The Workflow Runner miniapp is included in this package but is disabled by default.
To enable it you must set the environment variable WORKFLOW_RUNNER_ENABLED=true before starting ComfyUI.
By default the runner will not register its HTTP routes or static frontend when WORKFLOW_RUNNER_ENABLED is not set or set to a false value. This makes the runner opt-in and prevents accidental exposure of the runner endpoints.
Configuration is loaded from the repository-level .env file (at the project root).
Set WORKFLOW_RUNNER_ENABLED=true to enable the runner.
If you do enable it, ensure authentication/allowed-users are configured (see docs/WORKFLOW_RUNNER.md) to avoid unauthorised access.

Reusable, project-agnostic workflows can ship with LF Nodes. To add one to the Workflow Runner, follow these steps:
Create the workflow JSON file
Export your ComfyUI workflow and save it as modules/workflow_runner/workflows/<workflow_name>.json
Create the workflow Python module
Create a corresponding Python file modules/workflow_runner/workflows/<workflow_name>.py with:
_configure(prompt, inputs) that maps user inputs to workflow node inputsWorkflowCell objects for each user input (uploads, text fields, checkboxes, etc.)WorkflowCell objects for each output (images, strings, JSON, etc.)WorkflowNode object with metadata and export it as WORKFLOWRegister the workflow
Add your workflow module name to the _WORKFLOW_MODULES tuple in modules/workflow_runner/workflows/__init__.py
Update frontend types (if adding new output types)
If your workflow produces new output types:
web/workflow-runner/src/types/api.tsWorkflowNodeOutputs interface to include your new typeweb/workflow-runner/src/elements/components.ts and main.outputs.tsUpdate node outputs (if needed)
If using custom nodes, ensure they return data in the expected format:
OUTPUT_IS_LIST appropriately for batch/list outputsui.lf_output for frontend consumptionExample commit: See commit 2fbb49e which adds the caption_image_vision workflow, demonstrating all these steps including updating LF_DisplayString to support string outputs and frontend components to render them.
Project-owned workflows do not need to be copied into this published package.
Store each workflow's .py definition and .json graph together in an external
directory, then set WORKFLOW_RUNNER_EXTRA_WORKFLOW_ROOTS in the repository-level
.env. The setting accepts comma- or semicolon-separated absolute directories.
Set WORKFLOW_RUNNER_EXTRA_WORKFLOW_GROUPS to a matching ordered list of safe
display labels when the drawer should group each registered root separately.
Packaged LF Nodes workflows remain grouped by their domain; external definitions
are shown only under their custom registration group.
External definitions use the same workflows.custom import contract as local
custom workflows, so their existing relative imports and workflow IDs can remain
stable.
External roots are trusted Python source: every discovered .py module can run
code during Workflow Runner startup. Point the setting only at directories you
control, use unique module filenames and workflow IDs, and restart ComfyUI after
changing the configured roots or their contents.
Before queueing a large workflow, run the queue-free structural preflight from the LF Nodes repository root:
python -m modules.workflow_runner.scripts.workflow_preflight <workflow.json>
The command validates node/link integrity, verifies that every referenced LF
node type still exists, and exercises the same workflow-to-prompt conversion as
the runner. Add --require-all-lf-nodes when the file is intended to cover every
currently shipped LF node; missing coverage then becomes a failing exit status.
The image editor node (LF_LoadAndEditImages) allows users to load images from disk and perform editing operations such as inpainting, adjusting saturations, brightness, contrast, and more, all through an interactive interface.
It's possible to select the images from the file system tree and then send them downstream to other nodes for further processing.

The LLM nodes were tested with Koboldcpp, but any Open AI-compatible endpoint that does not require authentication/an API key should work. The model used in the workflows samples is UCLA-AGI/Llama-3-Instruct-8B-SPPO-Iter3 with ChaoticNeutrals/LLaVA-Llama-3-8B-mmproj-Updated.
Contributions to this repository are welcome, feel free to submit pull requests or open issues for discussion! To setup the environment clone this repository, then from the root open a terminal and run the command
pip install -r requirements.txt
This will install all the required dependencies for the Python backend.
To build the frontend, install Node.js with Corepack available, then run the command
corepack yarn install --immutable
This command will install all the dependencies. Note that the repository includes the compiled frontend sources, so you can skip this step if you don't plan to modify the frontend.
corepack yarn build
This command will compile all the frontend sources and generate/refresh the actual web directory.
MIT License
For an overview of how this nodes suite is structured and how it integrates with the UI, see:

Python
41.5%
JavaScript
41.0%
TypeScript
17.1%
Custom nodes with a touch of extra UX ✨ Client-side LLM chat, mid-workflow image editing, history for primitives, JSON manipulation, analytics nodes, CivitAI metadata fetching and saving... and more!
35
stars
967
commits
Python
primary language
Aug 29, 2026
updated

A suite of custom nodes for ComfyUI aimed at enhancing user experience with more interactive and visually engaging widgets.
Most UI elements used by the frontend belong to the LF Widgets webcomponents library, a modern collection of modular and customizable webcomponents built on Stencil.js specifically to integrate with LF Nodes.

The nodes span quite a few categories:
To see example workflows, check the example_workflows folder. For generic texture serialization, see DDS Output. For the current visual-novel node inputs and identity contract, see Visual Novel Nodes.
ComfyUI/custom_nodes folder.ComfyUI/custom_nodes folder.git clone https://github.com/lucafoscili/lf-nodes.git.The Workflow Runner miniapp is included in this package but is disabled by default.
To enable it you must set the environment variable WORKFLOW_RUNNER_ENABLED=true before starting ComfyUI.
By default the runner will not register its HTTP routes or static frontend when WORKFLOW_RUNNER_ENABLED is not set or set to a false value. This makes the runner opt-in and prevents accidental exposure of the runner endpoints.
Configuration is loaded from the repository-level .env file (at the project root).
Set WORKFLOW_RUNNER_ENABLED=true to enable the runner.
If you do enable it, ensure authentication/allowed-users are configured (see docs/WORKFLOW_RUNNER.md) to avoid unauthorised access.

Reusable, project-agnostic workflows can ship with LF Nodes. To add one to the Workflow Runner, follow these steps:
Create the workflow JSON file
Export your ComfyUI workflow and save it as modules/workflow_runner/workflows/<workflow_name>.json
Create the workflow Python module
Create a corresponding Python file modules/workflow_runner/workflows/<workflow_name>.py with:
_configure(prompt, inputs) that maps user inputs to workflow node inputsWorkflowCell objects for each user input (uploads, text fields, checkboxes, etc.)WorkflowCell objects for each output (images, strings, JSON, etc.)WorkflowNode object with metadata and export it as WORKFLOWRegister the workflow
Add your workflow module name to the _WORKFLOW_MODULES tuple in modules/workflow_runner/workflows/__init__.py
Update frontend types (if adding new output types)
If your workflow produces new output types:
web/workflow-runner/src/types/api.tsWorkflowNodeOutputs interface to include your new typeweb/workflow-runner/src/elements/components.ts and main.outputs.tsUpdate node outputs (if needed)
If using custom nodes, ensure they return data in the expected format:
OUTPUT_IS_LIST appropriately for batch/list outputsui.lf_output for frontend consumptionExample commit: See commit 2fbb49e which adds the caption_image_vision workflow, demonstrating all these steps including updating LF_DisplayString to support string outputs and frontend components to render them.
Project-owned workflows do not need to be copied into this published package.
Store each workflow's .py definition and .json graph together in an external
directory, then set WORKFLOW_RUNNER_EXTRA_WORKFLOW_ROOTS in the repository-level
.env. The setting accepts comma- or semicolon-separated absolute directories.
Set WORKFLOW_RUNNER_EXTRA_WORKFLOW_GROUPS to a matching ordered list of safe
display labels when the drawer should group each registered root separately.
Packaged LF Nodes workflows remain grouped by their domain; external definitions
are shown only under their custom registration group.
External definitions use the same workflows.custom import contract as local
custom workflows, so their existing relative imports and workflow IDs can remain
stable.
External roots are trusted Python source: every discovered .py module can run
code during Workflow Runner startup. Point the setting only at directories you
control, use unique module filenames and workflow IDs, and restart ComfyUI after
changing the configured roots or their contents.
Before queueing a large workflow, run the queue-free structural preflight from the LF Nodes repository root:
python -m modules.workflow_runner.scripts.workflow_preflight <workflow.json>
The command validates node/link integrity, verifies that every referenced LF
node type still exists, and exercises the same workflow-to-prompt conversion as
the runner. Add --require-all-lf-nodes when the file is intended to cover every
currently shipped LF node; missing coverage then becomes a failing exit status.
The image editor node (LF_LoadAndEditImages) allows users to load images from disk and perform editing operations such as inpainting, adjusting saturations, brightness, contrast, and more, all through an interactive interface.
It's possible to select the images from the file system tree and then send them downstream to other nodes for further processing.

The LLM nodes were tested with Koboldcpp, but any Open AI-compatible endpoint that does not require authentication/an API key should work. The model used in the workflows samples is UCLA-AGI/Llama-3-Instruct-8B-SPPO-Iter3 with ChaoticNeutrals/LLaVA-Llama-3-8B-mmproj-Updated.
Contributions to this repository are welcome, feel free to submit pull requests or open issues for discussion! To setup the environment clone this repository, then from the root open a terminal and run the command
pip install -r requirements.txt
This will install all the required dependencies for the Python backend.
To build the frontend, install Node.js with Corepack available, then run the command
corepack yarn install --immutable
This command will install all the dependencies. Note that the repository includes the compiled frontend sources, so you can skip this step if you don't plan to modify the frontend.
corepack yarn build
This command will compile all the frontend sources and generate/refresh the actual web directory.
MIT License
For an overview of how this nodes suite is structured and how it integrates with the UI, see:

Python
41.5%
JavaScript
41.0%
TypeScript
17.1%