Olm Liquify
Olm Liquify puts a Photoshop-style warp editor in your graph
- image
- image
There's a classic answer whenever someone posts "hands are weird" or "the jaw is too wide": fix it in an external editor, then run a light img2img pass to blend. Olm Liquify is that first step, except you never leave ComfyUI. Drop the node in, run the graph once, and an "Open Liquify Editor" button appears on the node. Click it and you get a real-time warping canvas - push, pull, twirl, pinch, expand, smooth - Photoshop's Liquify tool, minus the subscription. When you hit Apply and run the graph again, the warp comes out the other side as a normal IMAGE you can feed straight into img2img, a detailer, or a save node.
It's by Olli Sorjonen (@o-l-l-i), released mid-2026 with a solid reception on r/comfyui. He built it because he didn't want to depend on commercial tools for warp edits he needs constantly. The name's a lie in the best way: it calls no API and needs no key - everything happens locally, in your browser tab, against your own image.
How it works
The clever bit is how the interactivity is split between Python and JavaScript. On the first graph run the backend caches your source image and hands the frontend a cache_key. When you drag a brush, the JS editor posts stroke data to a local endpoint (/olm/api/liquify/stroke), the backend accumulates it into a displacement field - a two-channel (H, W, 2) array of per-pixel offsets, each stroke adding a Gaussian-falloff blob - and returns a warped preview via cv2.remap with BORDER_REFLECT. Painting at preview resolution keeps it fast; when you Apply, the field is resized back up to full source resolution and the graph's output is the real thing.
Two things worth knowing under the hood. First, the warp field is tied to its source by a hash: change the input image and the old field is silently ignored rather than misapplied. Second, nothing is persisted between ComfyUI restarts except .npz warp files you explicitly save - so the "run once to load, run again to apply" rhythm is the actual workflow, not a bug.
The inputs and outputs that matter
Honestly, image is the only input you'll ever touch by hand. The rest are plumbing: liquify_uid (defaults to auto-generated, scopes the warp cache to this node instance), workflow_name, liquify_version, and field_filename - set the last one to load a saved .npz warp instead of painting fresh. The single output, image, is the warped result, and it wires into anything that takes an IMAGE.
Installing it
Search "Olm Liquify" in ComfyUI Manager and install, or clone the old-fashioned way:
cd ComfyUI/custom_nodes
git clone https://github.com/o-l-l-i/ComfyUI-Olm-Liquify.git
pip install -r requirements.txt
Then restart ComfyUI. The requirements are just torch, numpy, and opencv-python - you almost certainly have the first two, and opencv-python is the only likely newcomer. No model downloads at all. One early-user gotcha: right after release the pack wasn't in Manager's registry yet, so if your search comes up empty, update Manager's cache or just clone.
Common gotchas
- The editor won't open until you've run the graph once. The backend needs the image cached. Run, then click.
- Still images only. No batch, no video frames - the author says so plainly.
- Edge artifacts show up when you warp hard against borders or strong edges. Multiple lighter strokes beat one heavy one, especially on faces.
- Restart ComfyUI and the cache is gone - re-run the graph to reload the image. A browser refresh can recover the preview while the backend still has it.
- The preview is a downscaled stand-in; the applied result is sampled at full resolution, so tiny details can look slightly different than in the editor.
One last thing: this is source-available, not OSI open source. You can use and experiment freely and your results are yours, but you can't redistribute or rebrand the code. If you're building a pack that bundles other people's work, read LICENSE.txt before shipping.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| liquify_version | STRING | init | — |
| liquify_uid | STRING | __AUTO_GENERATE__ | — |
| workflow_name | STRING | unknown_workflow | — |
| field_filename | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |