Nodes/ComfyTV/Layer Editor
ComfyUI Node

Layer Editor

A full 2D layer editor that lives inside a ComfyUI node

By jtydhr88·Created 3 months ago·Updated about 16 hours ago· 725
Layer Editor
    • image
    • images
    project_id
    parent_output_id0
    layer_state{}
    width1024
    height1024
    captured_image
    captured_images

    Layer Editor is where ComfyTV stops pretending to be a node pack and starts being an app. Open the node and you get a real layered compositing document - raster layers, text, vector shapes, parametric fills, per-layer masks, non-destructive transforms, undo, even PSD import/export - all inside a single ComfyUI node body. It's the "assemble the final art" step of a ComfyTV pipeline: generate your parts upstream, then composite them with actual layout control instead of a pile of blend nodes.

    ComfyTV is the canvas-style app layer on ComfyUI where every operation is its own node. This one lives in the Input category because it's a producer - you draw/compose in it and it hands finished images downstream.

    How it works. The editor is its own project, Pentrado, embedded in the node body (you can even try it standalone at pentrado.com). Everything you do in the editor is serialized into a layer_state JSON document - the node's single real state - and re-rendered when the document changes. On Run it persists the composite and hands it out. There's also a storyboard workbench in the same category that reuses this engine per board, adding onion skin, timeline playback and animatic export, but that's a sibling; this stage is the straight compositor.

    The inputs that matter. This is one of the few ComfyTV stages where you genuinely set almost nothing as a node parameter, because the work happens in the editor body:

    • layer_state - internal: the document JSON (layers, masks, text, transforms) written by the editor.
    • width / height - internal: the artboard size in pixels (64–4096, step 8).
    • captured_image / captured_images - internal: /view URLs of the composite and per-layer captures written by the editor on save.

    Don't touch any of them - they're populated by the node body. The outputs are what matter: image (a COMFYTV_IMAGE, the flattened composite) and images (a COMFYTV_IMAGES batch, one per layer), so you can wire the whole composite into an upscaler or send individual layers onward for separate treatment.

    Install. Install the pack once:

    cd ComfyUI/custom_nodes
    git clone https://github.com/jtydhr88/ComfyTV
    

    Restart ComfyUI (full restart, not a browser refresh) and the stage appears under ComfyTV → Input. ComfyUI Manager - search "ComfyTV" - works too. Zero Python dependencies (the pack's pyproject.toml dependency list is empty), and no model files - the editor is pure browser-side canvas, which is why it feels instant. The usual install trap: on ComfyUI Desktop or multi-install machines, clone into the running instance's path from the startup log or the node won't register.

    Where people get burned. The biggest confusion is expecting the node's widget inputs to do something - they're all internal, and beginners type into layer_state or fight with width expecting it to resize the artboard. It doesn't; the artboard size is set inside the editor body. Second: the outputs are only refreshed on capture, so a node downstream won't see your latest edit until you've re-run/saved from the editor. And one genuinely useful escape hatch: since it supports PSD import/export, you can do the heavy layout in the editor, export the PSD, and keep iterating in a real Photoshop session if the embedded editor ever feels small.

    CategoryComfyTV/Input

    Inputs (7)

    NameTypeDefaultDescription
    project_idSTRINGInternal — populated by the projectStore on the frontend.
    parent_output_idINT00–2147483647Internal — lineage parent set by spawn handlers on the frontend.
    layer_stateSTRING{}Internal — Layer Editor document JSON (layers/masks/text/transforms).
    widthINT102464–4096Internal — artboard width in pixels.
    heightINT102464–4096Internal — artboard height in pixels.
    captured_imageSTRINGInternal — /view URL of the last composite capture upload.
    captured_imagesSTRINGInternal — JSON images batch of the last per-layer capture.

    Outputs (2)

    NameTypeDescription
    imageCOMFYTV_IMAGE
    imagesCOMFYTV_IMAGES