Advanced Text Overlay
The ComfyUI text overlay that won't betray you with an Arial fallback
- image
- IMAGE
You've been there: you want a lower-third, a subtitle, or a meme caption burned into an image, so you reach for whatever text node you have, and the font quietly swaps to Arial. Core ComfyUI doesn't ship a real text-compositing node, and the classic answer, WAS Node Suite, has a text overlay buried in a giant toolbox. This node is the dedicated, opinionated version: one node, one job, and a font system that actually finds the font you asked for.
Advanced Text Overlay takes an image (or a batch of frames) plus a text string and returns the composited image. It's Pillow under the hood - per-character letter spacing, stroke, shadow, rounded background box, alignment - but the selling points are the parts people usually get wrong elsewhere. First, it resolves fonts by their true family name (via fontTools) rather than the filename, so "Californian FB" doesn't render as "califb" or fall through to Arial. Second, it understands a small HTML-like rich-text subset inline: <b>, <i>, <br>, and <span color="#FF0000"> or <span bg="#000"> for per-word color and highlights. That means you can write Title: <b>Episode 01</b><br><span color="#cccccc">Subtitle</span> and get mixed styling from one string instead of stacking nodes.
The inputs that matter
The full list is long (30-ish), but you'll actually touch maybe half a dozen:
text- multiline, supports\nand the inline tags above.font- a dropdown of fonts discovered on your system. If it's missing, the first scan (a few seconds) writes afont_cache.jsonin the pack folder, and after that loads are instant.font_size,letter_spacing,line_spacing,font_alignment- your basic typography.fill_color_hex/fill_alpha- white fill at full opacity is the default; the hex field is where most people live.stroke_enable,stroke_color_hex,stroke_thickness,stroke_alpha- the outline. Notestroke_thicknessis relative (0–1, scaled by font size), so 0.2 is a thin outline, not 0.2px.bg_enable,bg_color_hex,bg_alpha,bg_radius,bg_padding- the rounded background box behind the text. Off by default.shadow_enable,shadow_distance,shadow_color_hex,shadow_alpha- soft drop shadow.horizontal_alignment/vertical_alignmentplusx_shift/y_shift- placement. Defaults are center/middle.animate- flip this on for a batch and it fades or slides the text in overanimation_frames, then holds the final pose.animation_kindisfade_in/fade_out/move_from_top/move_from_bottom/move_from_left/move_from_right, withanimation_easeoflinear/ease_in/ease_out/ease_in_out.
The output is a single IMAGE, which you can wire to a Save or Preview node. The layout is computed once and cached, so a long batch doesn't re-measure every frame - that's the "batch-smart" bit, and it's real: with a 200-frame batch you'd notice the difference.
Installing it
Same as any custom node. Fastest via ComfyUI Manager - search "Advanced Text Overlay" - or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/scofano/ComfyUI-Advanced-TextOverlay
pip install -r requirements.txt
Then restart ComfyUI. The pack's requirements.txt pulls numpy, torch, Pillow, imageio, tqdm, and fonttools - no model files, no GPU weight downloads, nothing heavy. The nodes land under the Advanced Text Overlay category. If you already have most of those installed, this is a two-minute setup.
Where people get burned
The font dropdown is the trap. It only shows fonts that exist on your machine, so a workflow you download will reference a font you don't have - and the node falls back to Arial, which is exactly the bug this pack was built to avoid. When that happens, check your installed fonts first, then swap the font dropdown. Also: pause_frames_before_start on this image node is in frames, not seconds - it has no FPS to convert with, and the README is upfront about it. The video sibling (Advanced Text Overlay - Video) uses seconds instead, which is a genuinely easy thing to trip over if you're copying settings between the two.
One honest caveat: the rich text is a "safe, limited subset," not HTML. Unsupported tags render their text without styling, and bold/italic only work if your chosen font has a matching variant - otherwise you get the regular weight and no error. That's the one thing that'll make you think it's broken when it isn't.
Inputs (34)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| text | STRING | the quick brown fox jumps over the lazy dog | — |
| all_caps | BOOLEAN | false | — |
| font | COMBO | Arial | 33 options: Arial, Arial Black, Arial Narrow, C059, Comic Sans MS, Courier New, +27 |
| font_size | INT | 321–9999 | — |
| letter_spacing | FLOAT | 0.0-10–50 | — |
| font_alignment | COMBO | center | 3 options: left, center, right |
| fill_color_hex | STRING | #FFFFFF | — |
| fill_alpha | FLOAT | 1.000–1 | — |
| padding | INT | 160–1024 | — |
| vertical_alignment | COMBO | middle | 3 options: top, middle, bottom |
| y_shift | INT | 0-1024–1024 | — |
| horizontal_alignment | COMBO | center | 3 options: left, center, right |
| x_shift | INT | 0-1024–1024 | — |
| line_spacing | FLOAT | 4.00–50 | — |
| stroke_enable | BOOLEAN | true | — |
| stroke_color_hex | STRING | #000000 | — |
| stroke_thickness | FLOAT | 0.200–1 | — |
| stroke_alpha | FLOAT | 1.000–1 | — |
| bg_enable | BOOLEAN | false | — |
| bg_padding | INT | 80–1024 | — |
| bg_radius | INT | 80–512 | — |
| bg_color_hex | STRING | #000000 | — |
| bg_alpha | FLOAT | 0.500–1 | — |
| shadow_enable | BOOLEAN | false | — |
| shadow_distance | INT | 3-50–50 | — |
| shadow_color_hex | STRING | #000000 | — |
| shadow_alpha | FLOAT | 0.700–1 | — |
| animate | BOOLEAN | false | — |
| animation_kind | COMBO | fade_in | 6 options: fade_in, fade_out, move_from_top, move_from_bottom, move_from_left, move_from_right |
| animation_frames | INT | 321–1000 | — |
| animation_ease | COMBO | ease_in_out | 4 options: linear, ease_in, ease_out, ease_in_out |
| animation_opacity_target | FLOAT | 1.000–1 | — |
| pause_frames_before_start | INT | 00–100000 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |