| name | managing-templates |
| description | Manages ComfyUI workflow templates end-to-end: add new templates and rename existing ones (files, index metadata, bundles, i18n, package sync). Use when asked to: add a template, create a new template, submit a workflow, rename a template, retitle a template slug, change a template name, rename workflow template, onboard a template, register a template, ship a template. Triggers on: add template, new template, new workflow, rename template, rename workflow, change template name, template rename. |
Managing Templates
Covers adding new templates and renaming existing ones in this repository.
Related skills (do not replace this one):
/managing-bundles โ move between bundles / categories / order
/managing-thumbnails โ thumbnail-only work
/managing-translations โ broader i18n work
/managing-mcp-index โ MCP index only
Shared Rules
- Never modify scripts, build tooling, or CI configuration.
- Template names must be
snake_case โ no spaces, dots, or special characters.
name must match the workflow JSON filename (without .json).
- Always run
python3 scripts/sync/sync_bundles.py after editing bundles.json or renaming template assets.
- Always validate after structural changes (see Validation below).
- For new templates, assign media to
media-assets-01 โ see scripts/docs/frozen_bundles.md.
- Bump root
pyproject.toml only for intentional PyPI releases (release label).
- Use double-quotes
" in all JSON files.
- Model download URLs must produce filenames that exactly match
widgets_values in the workflow JSON.
- Package copies under
packages/*/src/**/templates/ are gitignored; regenerate via sync_bundles.py, do not hand-edit.
Decide the operation
Adding a Workflow Template
Step 1 โ Obtain the Workflow JSON
Place your_template_name.json in templates/.
Step 2 โ Thumbnails
In templates/:
{template_name}-1.webp # required
{template_name}-2.webp # optional โ compareSlider / hoverDissolve
| Variant | Files needed |
|---|
(default) / video / audio / zoomHover | -1 only |
compareSlider / hoverDissolve | -1 and -2 |
Prepare as webp (lossy ~65%), reasonable resolution; animated webp for video thumbs before resize.
Step 3 โ Entry in templates/index.json
Add the object to the right category's templates array.
Required: name, description, mediaType (image | video | audio | 3d), mediaSubtype (usually webp).
Common optional: title, tags, models, logos, date, openSource, requiresCustomNodes, thumbnailVariant, tutorialUrl, usage, size, vram, searchRank, io, thumbnail.
{
"name": "text_to_video_wan",
"description": "Generate videos from text descriptions.",
"mediaType": "image",
"mediaSubtype": "webp",
"tutorialUrl": "https://comfyanonymous.github.io/ComfyUI_examples/wan/"
}
Step 4 โ Bundle
Add the name to the correct array in bundles.json. New media โ media-assets-01.
python3 scripts/sync/sync_bundles.py
Step 5 โ Embed Model Metadata
For every model-loading node (UNETLoader, VAELoader, CLIPLoader, etc.), add properties.models[]:
| Field | Required | Notes |
|---|
name | yes | Must match widgets_values |
url | yes | Direct download URL |
hash | yes | SHA-256 |
hash_type | yes | "SHA256" |
directory | yes | e.g. diffusion_models, vae, text_encoders |
Step 6 โ Node Versions (Optional)
"properties": {
"Node name for S&R": "SaveWEBM",
"cnr_id": "comfy-core",
"ver": "0.3.26"
}
Step 7 โ Sync and Validation
python3 scripts/sync/sync_bundles.py
python3 scripts/validate/validate_templates.py
python3 scripts/validate/validate_thumbnails.py
Step 8 โ i18n
sync_data.py does not invent translations. It only applies title / description strings that already exist in scripts/data/i18n.json into templates/index.{locale}.json. Technical fields are copied from English index.json; tags use mappings also stored in i18n.json.
- Maintain translations in
scripts/data/i18n.json under templates.{name} (add or update locale strings). Until a locale string differs from English, that language stays pending / English fallback.
{
"templates": {
"your_template_name": {
"title": {
"en": "Your Template Title",
"zh": "ๆจ็ๆจกๆฟๆ ้ข",
"ja": "ใใณใใฌใผใใฎใฟใคใใซ"
},
"description": {
"en": "Your template description",
"zh": "ๆจ็ๆจกๆฟๆ่ฟฐ",
"ja": "ใใณใใฌใผใใฎ่ชฌๆ"
}
}
}
}
- Then run sync so locale index files pick up the new/updated strings:
python3 scripts/sync/sync_data.py --templates-dir templates
Order matters: edit i18n.json first, then sync. Re-run sync after any later translation edits. For coverage checks and broader i18n work, use /managing-translations.
Step 9 โ Version (release PRs only)
See scripts/docs/frozen_bundles.md.
Renaming a Template
Rename the template slug (name / filenames), not just the display title.
Example: audio_sync_so_lip_sync_video โ api_sync_so_lip_sync_video.
Step 1 โ Discover every reference
rg -l --glob '!**/node_modules/**' --glob '!**/.git/**' 'OLD_NAME'
ls templates/OLD_NAME* thumbnail/OLD_NAME* output/OLD_NAME* 2>/dev/null
Typical touch points:
| Location | What changes |
|---|
templates/{name}.json | rename file |
templates/{name}-1.webp (and -2.webp if any) | rename file |
thumbnail/{name}_thumbnail.* | rename if present |
output/{name}.* | rename if present |
templates/index.json | name, io.outputs[].file, thumbnail[] paths |
templates/index.*.json | same string refs as English index |
bundles.json | bundle membership string |
scripts/data/i18n.json | translation keys keyed by template name |
templates/index.mcp.json | if the template is already in MCP index |
site/overrides/templates/{name}.json | rename override file + internal name if present |
packages/core/.../manifest.json | regenerated by sync (do not hand-edit) |
Do not bulk-replace inside unrelated binary files. Prefer an explicit file list over a repo-wide rg \| perl loop (large trees can hang).
Step 2 โ Rename assets with git mv
git mv templates/OLD_NAME.json templates/NEW_NAME.json
git mv templates/OLD_NAME-1.webp templates/NEW_NAME-1.webp
git mv templates/OLD_NAME-2.webp templates/NEW_NAME-2.webp
git mv thumbnail/OLD_NAME_thumbnail.mp4 thumbnail/NEW_NAME_thumbnail.mp4
git mv output/OLD_NAME.mp4 output/NEW_NAME.mp4
Adjust extensions to match what exists (.webp, .mp4, etc.).
Step 3 โ Update text references
Replace OLD_NAME โ NEW_NAME in every text/JSON file from Step 1, especially:
"name": "OLD_NAME"
bundles.json entry
io.outputs[].file (e.g. OLD_NAME.mp4)
thumbnail: ["thumbnail/OLD_NAME_..."]
- i18n object keys
Use a targeted replace on the known file list (not a whole-repo scan that touches binaries).
Step 4 โ Sync packages
python3 scripts/sync/sync_bundles.py
Confirms manifest.json ids/filenames point at NEW_NAME, and regenerates gitignored package template copies.
Step 5 โ i18n / MCP if needed
Step 6 โ Verify
rg -l --glob '!**/node_modules/**' --glob '!**/.git/**' 'OLD_NAME' || echo '(none)'
ls templates/NEW_NAME.json templates/NEW_NAME-1.webp
python3 scripts/validate/validate_templates.py
python3 scripts/validate/validate_thumbnails.py
No remaining OLD_NAME refs should remain (except unrelated historical docs). Bundle membership stays the same unless the user also asks to move bundles (/managing-bundles).
Rename caveats
- Renaming the slug is a breaking change for anything that pins the old template id (Comfy Cloud, docs links, MCP callers). Mention that if relevant.
- Do not bump
pyproject.toml for a rename-only PR unless it is an intentional release.
- Display-only title/description edits are not a rename; edit
index.json / i18n only.
Validation (shared)
python3 scripts/sync/sync_bundles.py
python3 scripts/validate/validate_templates.py
python3 scripts/validate/validate_thumbnails.py
Common User Requests
| User says | Agent action |
|---|
| "Add this workflow as a template" | Adding Steps 1โ9 |
| "I have a JSON file, make it a template" | Adding from Step 1 |
| "Rename X to Y" / "ๆ X ้ๅฝๅๆ Y" | Renaming Steps 1โ6 |
| "Change the template name / slug" | Renaming (not title-only) |
| "Add a thumbnail for template X" | Prefer /managing-thumbnails |
| "What bundle?" | New media โ media-assets-01; legacy media-* frozen |
| "Validate my template" | Validation section |
| "Sync translations" / "ๅ ็ฟป่ฏ" | Edit scripts/data/i18n.json first, then Adding Step 8 / /managing-translations |
File Quick-Reference
| File / Dir | Purpose |
|---|
templates/ | Workflow JSON + thumbnails |
templates/index.json | Master English manifest |
templates/index.{locale}.json | Locale manifests |
thumbnail/, output/ | Optional preview/output media naming {name}_โฆ |
bundles.json | Template โ bundle |
scripts/data/i18n.json | Source of truth for title/description (and tag) translations; edit here before sync |
scripts/sync/sync_bundles.py | Manifest + copy assets into packages |
scripts/sync/sync_data.py | Apply i18n.json translations into locale indexes (does not invent translations) |
scripts/validate/validate_templates.py | Template JSON validation |
scripts/validate/validate_thumbnails.py | Thumbnail validation |
scripts/docs/frozen_bundles.md | Frozen legacy bundle policy |