Skip to main content

comfyui-node-datatypes

ComfyUI data types - IMAGE, LATENT, MASK, CONDITIONING, MODEL, CLIP, VAE, AUDIO, VIDEO, 3D types, widget types, and custom types. Use when working with ComfyUI tensors, model types, or defining input/output data types.

Source facts

Repository
jtydhr88/comfyui-custom-node-skills
Last source activity
October 17, 2026 at 01:09
Detected SKILL.md language
English
Stars
298
Forks
28

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
comfyui-node-datatypes
description
ComfyUI data types - IMAGE, LATENT, MASK, CONDITIONING, MODEL, CLIP, VAE, AUDIO, VIDEO, 3D types, widget types, and custom types. Use when working with ComfyUI tensors, model types, or defining input/output data types.
# ComfyUI Data Types ComfyUI uses specific data types for node inputs and outputs. Understanding tensor shapes and data formats is essential. ## Complete Type Reference ### Tensor/Data Types | Type | V3 Class | Format | Description | |---|---|---|---| | IMAGE | `io.Image` | `torch.Tensor [B,H,W,C]` float32 0-1 | Batch of RGB images | | MASK | `io.Mask` | `torch.Tensor [H,W]` or `[B,H,W]` float32 0-1 | Grayscale masks | | LATENT | `io.Latent` | `{"samples": Tensor[B,C,H,W] or [B,C,T,H,W], "noise_mask"?: Tensor, "batch_index"?: list[int], "type"?: str}` | Latent space (4D image / 5D video) | | CONDITIONING | `io.Conditioning` | `list[tuple[Tensor, PooledDict]]` | Text conditioning with pooled outputs | | AUDIO | `io.Audio` | `{"waveform": Tensor[B,C,T], "sample_rate": int}` | Audio data | | VIDEO | `io.Video` | `VideoInput` ABC | Video data (abstract base class) | | SIGMAS | `io.Sigmas` | `torch.Tensor` 1D, length steps+1 | Noise schedule | | NOISE | `io.Noise` | Object with `generate_noise()` | Noise generator | | LORA_MODEL | `io.LoraModel` | `dict[str, torch.Tensor]` | LoRA weight deltas | | LOSS_MAP | `io.LossMap` | `{"loss": list[torch.Tensor]}` | Loss map | | TRACKS | `io.Tracks` | `{"track_path": Tensor, "track_visibility": Tensor}` | Motion tracking data | | WAN_CAMERA_EMBEDDING | `io.WanCameraEmbedding` | `torch.Tensor` | WAN camera embeddings | | LATENT_OPERATION | `io.LatentOperation` | `Callable[[Tensor], Tensor]` | Latent transform function | | TIMESTEPS_RANGE | `io.TimestepsRange` | `tuple[int, int]` | Range 0.0-1.0 | | DICT | `io.Dict` | `dict` | Generic dictionary | | ARRAY | `io.Array` | `list` | Generic list/array | | LAYERS | `io.Layers` | `{"version": int, "canvas"?: (w, h), "layers": list[LayerItem]}` | Layer stack (v0.31+); LayerItem: `image` tensor, `type: "raster"`, `z_index`, optional `x`, `y`, `mask`, `name`, `opacity`, `blend_mode` (`io.Layers.BlendMode`), `visible`, `flip_h/v`, `rotation`, `w`, `h` | ### Model Types (opaque, typically pass-through) | Type | V3 Class | Python Type | |---|---|---| | MODEL | `io.Model` | `ModelPatcher` | | CLIP | `io.Clip` | `CLIP` | | VAE | `io.Vae` | `VAE` | | CONTROL_NET | `io.ControlNet` | `ControlNet` | | CLIP_VISION | `io.ClipVision` | `ClipVisionModel` | | CLIP_VISION_OUTPUT | `io.ClipVisionOutput` | `ClipVisionOutput` | | STYLE_MODEL | `io.StyleModel` | `StyleModel` | | GLIGEN | `io.Gligen` | `ModelPatcher` (wrapping Gligen) | | UPSCALE_MODEL | `io.UpscaleModel` | `ImageModelDescriptor` | | BACKGROUND_REMOVAL | `io.BackgroundRemoval` | `BackgroundRemovalModel` (e.g. BiRefNet) | | LATENT_UPSCALE_MODEL | `io.LatentUpscaleModel` | Any | | SAMPLER | `io.Sampler` | `Sampler` | | GUIDER | `io.Guider` | `CFGGuider` | | HOOKS | `io.Hooks` | `HookGroup` | | HOOK_KEYFRAMES | `io.HookKeyframes` | `HookKeyframeGroup` | | MODEL_PATCH | `io.ModelPatch` | Any | | AUDIO_ENCODER | `io.AudioEncoder` | Any | | AUDIO_ENCODER_OUTPUT | `io.AudioEncoderOutput` | Any | | PHOTOMAKER | `io.Photomaker` | Any | | POINT | `io.Point` | Any | | FACE_ANALYSIS | `io.FaceAnalysis` | Any | | BBOX | `io.BBOX` | Any | | SEGS | `io.SEGS` | Any | ### 3D Types | Type | V3 Class | Python Type | Description | |---|---|---|---| | MESH | `io.Mesh` | `MESH(vertices, faces)` | 3D mesh with vertices + faces tensors | | VOXEL | `io.Voxel` | `VOXEL(data)` | Voxel data tensor | | SPLAT | `io.Splat` | `SPLAT` | Gaussian splat data | | FILE_3D | `io.File3DAny` | `File3D` | Any supported 3D format | | FILE_3D_GLB | `io.File3DGLB` | `File3D` | Binary glTF | | FILE_3D_GLTF | `io.File3DGLTF` | `File3D` | JSON-based glTF | | FILE_3D_FBX | `io.File3DFBX` | `File3D` | FBX format | | FILE_3D_OBJ | `io.File3DOBJ` | `File3D` | OBJ format | | FILE_3D_STL | `io.File3DSTL` | `File3D` | STL format (3D printing) | | FILE_3D_USDZ | `io.File3DUSDZ` | `File3D` | Apple AR format | | FILE_3D_PLY | `io.File3DPLY` | `File3D` | PLY (point cloud / splat) | | FILE_3D_SPLAT | `io.File3DSPLAT` | `File3D` | .splat gaussian splat file | | FILE_3D_SPZ | `io.File3DSPZ` | `File3D` | Compressed splat (.spz) | | FILE_3D_KSPLAT | `io.File3DKSPLAT` | `File3D` | .ksplat format | | FILE_3D_SPLAT_ANY | `io.File3DSplatAny` | `File3D` | Any splat format | | FILE_3D_POINT_CLOUD_ANY | `io.File3DPointCloudAny` | `File3D` | Any point cloud format | | SVG | `io.SVG` | `SVG` | Scalable vector graphics | | LOAD_3D | `io.Load3D` | `Model3DDict` (see below) | 3D model with renders | | LOAD_3D_ANIMATION | `io.Load3DAnimation` | Same as Load3D | Animated 3D model | | LOAD3D_CAMERA | `io.Load3DCamera` | `CameraInfo` (see below) | 3D camera info | | LOAD3D_MODEL_INFO | `io.Load3DModelInfo` | `list[Model3DTransform]` | Per-model transforms (position/quaternion/scale) | **Load3D.Model3DDict**: `{"image": str, "mask": str, "normal": str, "camera_info": CameraInfo, "recording"?: str, "model_3d_info"?: list[Model3DTransform]}` **Load3DCamera.CameraInfo** (right-handed, Y-up, camera looks down -Z): required keys `position`, `target`, `zoom`, `cameraType` (`'perspective' | 'orthographic'`); optional keys `quaternion` (camera world rotation), `useCustomUp` (bool, v0.40+: use the quaternion's up instead of world +Y), `fov` (vertical, degrees, perspective only), `aspect`, `near`, `far`, `frustum` (orthographic only: `{left, right, top, bottom}`). **Load3DModelInfo.Model3DTransform**: `{"position": dict, "quaternion": dict, "scale": dict}` in world space. ### Widget Types (create UI controls) | Type | V3 Class | Python Type | Description | |---|---|---|---| | INT | `io.Int` | `int` | Integer with min/max/step | | FLOAT | `io.Float` | `float` | Float with min/max/step/round | | STRING | `io.String` | `str` | Text (single/multi-line) | | BOOLEAN | `io.Boolean` | `bool` | Toggle with labels | | COMBO | `io.Combo` | `str` | Dropdown selection | | COMBO (multi) | `io.MultiCombo` | `list[str]` | Multi-select dropdown | | COLOR | `io.Color` | `str` (hex) | Color picker, default `#ffffff` | | COLORS | `io.Colors` | `list[str]` (hex) | Color palette (list of colors) | | BOUNDING_BOX | `io.BoundingBox` | `{"x": int, "y": int, "width": int, "height": int}` | Rectangle region | | BOUNDING_BOXES | `io.BoundingBoxes` | `list[{"x", "y", "width", "height", "metadata": dict}]` | Multiple labeled regions | | CURVE | `io.Curve` | `list[tuple[float, float]]` | Spline curve points | | RANGE | `io.Range` | `RangeInput` (min/max + optional midpoint) | Levels/range editor with gradient display | | IMAGECOMPARE | `io.ImageCompare` | `dict` | Image comparison widget | | WEBCAM | `io.Webcam` | `str` | Webcam capture widget | | HISTOGRAM | `io.Histogram` | `list[int]` | Histogram bin counts | | VIDEO_EDIT | `io.VideoEdit` | `{"trim"?: {start_time, duration}, "crop"?: {x, y, width, height}}` | Video trim/crop editor (`features=["trim","crop"]`) | | RESOLUTION_PREVIEW | `io.ResolutionPreview` | `dict` | Live resolution preview bound to other widgets by name | | COMPOSITOR | `io.Compositor` | `dict` (LayerState) | Layer-editor state, default `{}` | | CAMERA_INFO_STATE | `io.CameraInfoState` | `dict` | Camera editor state (input only) | ### Special Types | Type | V3 Class | Description | |---|---|---| | `*` (ANY) | `io.AnyType` | Matches any type | | COMFY_MULTITYPED_V3 | `io.MultiType` | Accept multiple specific types on one input | | COMFY_MATCHTYPE_V3 | `io.MatchType` | Generic type matching across inputs/outputs | | COMFY_AUTOGROW_V3 | `io.Autogrow` | Dynamic growing inputs | | COMFY_DYNAMICCOMBO_V3 | `io.DynamicCombo` | Combo that reveals sub-inputs per option | | COMFY_DYNAMICSLOT_V3 | `io.DynamicSlot` | Connection slot that reveals sub-inputs when connected (not yet used by core nodes) | | COMFY_DYNAMICGROUP_V3 | *(internal `_DynamicGroup`)* | Repeated widget rows; not exported, unstable — do not use (frontend support since v1.57.0) | | FLOW_CONTROL | `io.FlowControl` | Internal testing only | | ACCUMULATION | `io.Accumulation` | Internal testing only | ## IMAGE Type Images are `torch.Tensor` with shape `[B, H, W, C]`: - **B** = batch size (1 for single image) - **H** = height in pixels - **W** = width in pixels - **C** = channels (3 for RGB, values 0.0-1.0) ```python import torch import numpy as np from PIL import Image as PILImage class ImageProcessor(io.ComfyNode): @classmethod def define_schema(cls): return io.Schema( node_id="ImageProcessor", display_name="Image Processor", category="image", inputs=[io.Image.Input("image")], outputs=[io.Image.Output("IMAGE")], ) @classmethod def execute(cls, image): b, h, w, c = image.shape result = torch.clamp(image * 1.5, 0.0, 1.0) return io.NodeOutput(result) ``` ### Loading / Saving Images ```python from PIL import ImageOps # Load from file → tensor def load_image(path): img = PILImage.open(path) img = ImageOps.exif_transpose(img) # fix rotation from camera EXIF if img.mode == "I": # handle 16-bit images img = img.point(lambda i: i * (1 / 255)) img = img.convert("RGB") return torch.from_numpy(np.array(img).astype(np.float32) / 255.0).unsqueeze(0) # Tensor → save to file def save_image(tensor, path): if tensor.dim() == 4: tensor = tensor[0] PILImage.fromarray(np.clip(255.0 * tensor.cpu().numpy(), 0, 255).astype(np.uint8)).save(path) # Batch operations batch = torch.cat([img1, img2], dim=0) # stack into batch single = image[i] # extract from batch [H,W,C] single_batch = image.unsqueeze(0) # add batch dim [1,H,W,C] ``` ## MASK Type `torch.Tensor` with shape `[H, W]` or `[B, H, W]`, values 0.0-1.0. ```python # Invert mask
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub