Tag Merge

:placard: Summary Merge similar tags (English/Japanese/Chinese spelling variants) into canonical tags according to an editable mapping database. Ships with a curated Chinese-target map (395 targets / 2659 sources) — plain JSON, so you can build your own for any target language in the built-in editor. Pure UI plugin (JS + CSS only, no Python).
:link: Repository https://github.com/k6cc/stash-jav-tools/tree/main/tagMerge
:information_source: Source URL https://k6cc.github.io/stash-plugins/plugins/main/index.yml
:open_book: Install How to install a plugin?

Hi stashers,

Scrapers and multiple metadata sources leave tag libraries full of spelling variants of the same concept: 3P, 3P·4P, 3p, 3P, 4p — one idea, five tags, and your tag filter list becomes unusable. This plugin merges them according to a mapping database: scan → grouped preview → merge per group or all at once. Sources are deleted but their names are written into the target’s aliases (search keeps working); references are transferred by Stash’s own backend — no data loss.

A note on target language: the bundled map targets Chinese canonical names, because that’s how my own library is curated. If you want English or any other target language, the map is just a plain JSON file — follow the format below, build your own, and drop it in.

Works great paired with Performer Merge and JavStashLinker (see my topics) — performer-side and stash-id-side cleanup of the same family.

What it does

The mapping database

Plain JSON — hand-editable, or editable in the panel and exported:

{
 "_note": "keys starting with _ are ignored",
 "3P/4P": ["3P·4P", "3P、4P", "3p", "4P", "4p", "3P"],
 "口枷": ["ボールギャグ", "口球", "球形口塞"],
 "出轨/NTR": ["NTR", "不倫", "寝取り・寝取られ"]
}
  • Key = the target tag (auto-created during merge if it doesn’t exist). Value = the source tags to merge into it.
  • Keys starting with _ are ignored — an _-prefixed array entry is a disabled rule, restorable in the panel; string values are comments.
  • Source matching is normalized-exact: fullwidth→halfwidth, case-insensitive, ignores spaces and separators — no substring or fuzzy matching.
  • The bundled map: 395 targets / 2659 sources, curated from a scraper’s mapping_info.xml keyword groups plus real English tags from my library. Targets are Chinese — for other target languages, follow this format and build your own.

Scan & grouped preview

  • Every scan re-reads the mapping file — replace the file, re-scan, no restart needed.
  • Each group card shows the target first, its source count, and a new badge when the target tag doesn’t exist yet.
  • A variant annotation marks sources that matched as a normalized variant of the target without being listed in the map.
  • Source-level and group-level ignore for anything you don’t want merged.

Merge behavior

Uses Stash’s native tagsMerge:

  • The source tag’s references are transferred to the target; the source is deleted and its name written into the target’s aliases (old names remain searchable).
  • A missing target is auto-created, but only when the group has a valid source.
  • Chain prevention: a group’s target is never another group’s source.
  • Idempotent: already-merged or missing sources are skipped on re-run.
  • No delete operations: the plugin never removes a tag without a target.

The map editor

Built into the panel — the file in the plugin directory is always the single source of truth:

  • Every entry supports Edit / Save / Undo / Delete / Ignore, plus Add and Export file.
  • Ignore temporarily disables a map entry (the scan skips it) — restorable.
  • Real-time duplicate detection (duplicate targets/sources, sources equal to another entry’s target — the chain risk).
  • A Conflicts filter lists entries with conflicting sources, each with a one-click Clean.
  • Export file downloads the complete JSON in a compact one-line-per-entry format, original key order preserved.
  • After exporting, replace tag_merge_map.json in the plugin directory and re-scan — browser-side JS can’t write server files.

Real-world result

On my library, the bundled map simulates to: 261 groups merged / 617 source tags, 77 new targets created, tag count trimmed from 1470 to 930.

Notes

  • Merging deletes source tags — back up before the first run (Settings → Tasks → Backup).
  • Needs Stash v0.30+ (the ui.assets route).
  • No Python, no API key, works fully offline in any modern browser.
  • Preview ignores (source/group) are session-only and reset on the next scan; editor ignores (entries) are persistent and survive export.
  • The map is a static file and does not auto-update from scraper maps — edit or regenerate it manually.
  • “N unmatched sources” in a card is normal — names not in your library yet and sources already merged.
  • Mobile-friendly: panel usable down to 480px.

Screenshots

Install

Option 1: Download Release

  1. Go to Releases and download the latest tagMerge-vX.Y.Z.zip
  2. Unzip into your Stash plugins directory (files go directly in the tagMerge folder):
    • Windows: %USERPROFILE%\.stash\plugins\tagMerge\
    • Linux/macOS: ~/.stash/plugins/tagMerge/
  3. Stash → Settings → Plugins → Reload plugins

Option 2: Add plugin source

In Stash → Settings → Plugins → Available Plugins → Add Source, add:

Recommended (GitHub Pages):

https://k6cc.github.io/stash-plugins/plugins/main/index.yml

Fallback (raw URL, no Pages required):

https://raw.githubusercontent.com/k6cc/stash-plugins/main/plugins/main/index.yml

Then install Tag Merge from the list. Same unified source that carries JavStashLinker, Performer Merge, Studio Tools, sceneGallerySync, Scene Translate, and Binge (cn) — one source, install any.

Companion plugins

Plugin Synergy with Tag Merge
nfoSceneParser (fork) The parser writes tags onto scenes → with variants merged into canonical tags, incoming parsed tags land on the single correct tag instead of spawning new variants.
Performer Merge Performer-side twin: find and bulk-merge duplicate performers, with short-name alias cleanup and alias repair.
JavStashLinker Links JAVStash stash_ids onto performers — the stash-id-side cleanup of the same family.
Studio Tools Studio-side twin: merge duplicate studios with a per-field diff dialog.
Scene Translate Translate scene titles/details after the tag cleanup.

License: MIT. Feedback and bug reports welcome — if you build a map for another target language (English, Japanese, …) and are willing to share it, ping me; a community map collection would benefit everyone. Bug reports with the exact source/target names and your Stash version are gold.

AI Development Statement

From project setup, fault debugging and architecture refactoring to the writing and polishing of all Markdown‑formatted documents, artificial intelligence runs through the entire development workflow of this project, and the whole project is developed with the help of AI.

1 Like

The UI version allows for quick verification of duplicate names and conflicts within the mapping table. User-exported mapping tables are prioritized and will never be overwritten during plugin updates. If any English-speaking users wish to contribute their mapping tables, I can bundle them into the plugin for the next release.