Nodes/Mask Editor One/Mask Editor One
ComfyUI Node

Mask Editor One

A whole Photoshop-style mask editor crammed into one ComfyUI node

By ketle-man·Created 3 months ago·Updated about a month ago· 1
Mask Editor One
    • image
    • mask
    • inverted_mask
    • mask_image
    invert_maskfalse
    layer_data{}
    blur_radius0

    If you've ever tried to paint a decent mask with stock ComfyUI, you know the pain: a tiny canvas, one brush, no layers, and god help you if you need to fix one edge without redoing the whole thing. Mask Editor One is the answer - a modal, Photoshop-style mask editor that lives inside a single node, does all your masking work, and hands you clean IMAGE/MASK outputs when it's done.

    Why you'd reach for it

    In a wider workflow this is the mask-authoring front-end for inpainting, compositing, and ControlNet passes. It matters now more than it sounds like it should. The instruction-edit models (Qwen-Image-Edit, Flux Kontext) took over most of the "change this thing" jobs, but masks still own the cases where you need a precise boundary and bit-identical unmasked pixels. When the job is "keep everything except this one region exactly as-is," you still need a real editor.

    And stock ComfyUI doesn't really give you one. This node does: layers with add/subtract blending, per-layer visibility, 30-step undo, brush hardness and spacing, image brushes, even .abr Photoshop brush imports. It also bundles two AI helpers - SAM3 text-prompt segmentation and one-click BiRefNet background removal - so it covers the whole arc from "auto-cutout" to "hand-fix the hair."

    How it works

    The editor is browser-side: a ComfyUI extension plus a small PromptServer API. Click Edit Mask on the node and a modal opens with a tool sidebar - paint, color select, transparency extract, text, vector (Catmull-Rom splines), shapes, SAM3, and BiRefNet. Everything is layer-based, and the layer state gets serialized to JSON. At run time the Python process() pulls the background image from a server-side cache, composites the layers (add layers lighten, subtract layers clip), applies any invert/blur, and emits four outputs.

    Nice touch: the node implements IS_CHANGED as a hash of the cached background, so ComfyUI re-runs when you swap the BG instead of silently serving a stale result.

    The inputs that actually matter

    There are only three, and you'll touch two of them:

    • invert_mask (boolean) - flips the output black↔white. Two-way synced with the modal's Invert checkbox, so it doesn't matter which one you flip.
    • blur_radius (int, 0–200) - Gaussian blur on the output mask. Also synced with the modal slider. Handy for feathering an inpaint boundary without dragging in a Blur Mask node.
    • layer_data (string) - the editor state JSON. Normally auto-updated; leave it alone.

    Outputs: image and mask are the headline - mask wires into any MASK input (VAE Encode for Inpaint, ControlNet, wherever). inverted_mask is the same mask flipped, which saves you a node. mask_image is the mask as an RGB image for nodes that want IMAGE. image is your loaded background if you set one, otherwise the mask rendered as an image.

    Gotcha: you can't wire an image in

    The original node had optional image/mask inputs; the author removed them. Now the image comes only from the Load Image button or by dropping a file on the node preview. That's the point of the fixed 160px preview - it's your drop zone. If you're used to feeding a tensor from the graph, this will trip you up once, then you'll forget it was ever a problem.

    Install

    ComfyUI Manager → search "Mask Editor One", or:

    cd ComfyUI/custom_nodes
    git clone https://github.com/ketle-man/comfyui-mask-editor-one
    pip install -r requirements.txt
    

    Then restart ComfyUI - it lands under image/masking. Dependencies are light (torch, torchvision, numpy, Pillow, sam3); the only heavy stuff is optional:

    • SAM3 tool: drop checkpoints into ComfyUI/models/sam3/ (e.g. sam3.safetensors). Note facebook/sam3 is a gated HuggingFace model - accept the license, then huggingface-cli login or set HF_TOKEN.
    • BiRefNet tool: birefnet.safetensors into ComfyUI/models/background_removal/. This one uses ComfyUI's native comfy.bg_removal_model, so no extra libraries - and it's the model ComfyUI shipped in core, so you're on solid ground. It only loads into VRAM when you actually run it.

    Troubleshooting

    • SAM3 not showing up in the dropdown - filenames must contain sam3, and TorchScript/JIT-saved files are skipped on purpose. And if you skipped the HF gating step, that's your auth error right there.
    • BiRefNet panel says error - model file missing or wrong filename. It should read "Model found" when it's set up; first inference takes a second or two to load.
    • Old workflows with a missing node - the class was renamed from MaskEditorNode to MaskEditorOne. Saved workflows referencing the old name need the node replaced.
    • Keep it updated - the author's been patching real stuff (path traversal fixes, a 100 MB request cap, safe torch.load). That's the kind of maintenance you want to stay current on.

    For the money, this is the one node I'd actually reach for over a stack of mask utility nodes - the layer workflow alone is worth the install.

    Categoryimage/masking

    Inputs (3)

    NameTypeDefaultDescription
    invert_maskBOOLEANfalse
    layer_dataoptSTRING{}
    blur_radiusoptINT00–200

    Outputs (4)

    NameTypeDescription
    imageIMAGE
    maskMASK
    inverted_maskMASK
    mask_imageIMAGE