Skip to content

Layout & mod.json ​

This page is the single authoritative table of mod.json fields. Other cards only link here when they mention a field, they never repeat the list.


Directory layout ​

text
my_mod/
├── mod.json                 # required (or manifest.json)
├── locales/                 # recommended: plugin self-contained i18n strings (all types)
│   ├── zh-CN.json
│   └── en-US.json
├── assets/icons/            # recommended: plugin-specific vector SVG icons (Emoji / character icons rejected)
├── icon.svg                 # recommended; icon.png / webp / jpg are auto-detected too
├── README.md                # optional, shown in the hub listing
├── libs/  vendor/           # optional: plugin-private Python dependencies (see Runtime environment)
├── theme.json               # type=theme
├── terms.json               # type=glossary (the only glossary format)
├── ja.json                  # type=i18n (full language pack)
├── provider.py              # Python entry point
└── *.qml                    # ui_extensions

Rules:

  • One MOD = one folder, id globally unique; the directory name should ideally match id but that is not enforced.
  • After a workshop install the directory name = the plugin id (<data dir>/workshop/<id>/) — so never assume the directory name, see Prerequisite plugins.
  • Binary runtimes go into a plugin-private directory (bin/, llama/ and the like), not into data/models/ (that is a weights-only directory; a user clicking "clear cache" would damage them by mistake).
  • Single-package size limit 20 MB, see Packaging & size limit.

Field table ​

FieldRequiredDefaultNotes
idYes—Globally unique, shaped like myteam.mt.deeplx. A missing id is rejected outright. The reserved official segments builtin.* / community.* / workshop.* may not be used
nameRecommendedUntitled MODDisplay name
versionRecommended1.0.0Semantic version. Local loading may omit it; required as x.y.z when publishing to the Plugin Hub, and a new version must be higher than the highest online version (editable right on the publish page)
authorRecommendedUnknown author—
descriptionNo""Hub blurb
typeRecommendedglossarySee Type overview
entrypointType-dependent""See "entrypoint rules" below
iconNoAuto-detectedsvg / png / webp / jpg
preview_imageNo—Relative path of the hub preview image
tagsNo[]Containing cloud → treated as a cloud API; containing local / offline → local offline. Decides whether the settings page shows a model card and a hardware rating
documentation_urlNo""External link to official docs (shown on the card)
target_app_versionYes (external/hub plugins)—Adaptation generation. Write "0.2". Omitting it is always judged "version mismatch" and refuses recognition and installation (built-ins and bundled extensions/ are exempt); see Compatibility & version gates
min_app_versionNo1.0.0Minimum compatible client version. 1.0.0 = no restriction; see Compatibility & version gates
tierNofreefree / pro / community
supported_langsNo[]Source language capability list; used for source-language clamping and card display. MT target languages belong in target_langs
target_langsNo (recommended for MT)Falls back to supported_langsTranslation target capability catalog; drives the languages users can activate in the caption "translate to" dropdown. Supports codes such as zh-TW / pt-BR; when empty, the generic 33-language capability applies. See Language codes & translatable languages
aliasesNo[]Short-name aliases (e.g. ["cool"]); the settings page / routing resolves them back to the full id
requires_hfNoInferred from tags/idfalse = pure API/cloud, startup may skip the transformers warm-up; true = needs HF
requires_cudaNo—false = does not hard-require NVIDIA (AMD ROCm / Vulkan / CPU are all fine) → the host stops showing the "CUDA required" red box
model_artifactsNo[]Local model artifact declarations, see Model artifacts
requires_pluginsNo[]Prerequisite plugin dependencies (≤ 8), see Prerequisite plugins
requires_runtimeNo[]Host runtime dependencies (≤ 4), see Host runtimes
capabilitiesNo{}Engine capability declaration (voice list / cloning / removal / native speed), see Capability declaration
config_schemaNo[]Declarative config form, see config_schema
ui_extensionsNo{}Slot → QML file mapping, see UI slots
hotkeysNo[]Declarative global hotkeys, see Global hotkeys
host_eventsNo[]Host event names to receive (["*"] = all), see Event bus
permissionsNo[]Capability declaration strings (net / clipboard / hotkey / window…), used for hub display and future gates
supports_glossaryNoInferred from type/tags/idtrue = natively consumes the glossary / hotwords
style_layerNofull (theme only)full / material / typography / effects
has_settings_tab / tab_id / tab_titleNo—Standalone settings tab, see Custom settings view
language_code / language_nameNo—i18n only
enabledNofalse for theme/i18n, true otherwiseInitial enabled state (the user's switch overrides it)
source_lang / target_langNo""Default language direction for glossary-like plugins

What must not be written into mod.json: window_backdrop (it is ignored) — it belongs to theme.json, see theme.

⚠️ target_app_version is the only field that makes your plugin uninstallable when omitted. Without it: dropping the folder into extensions/ still keeps it off the list, and Steam / Web Hub packages are refused outright. A 0.1.x plugin needs this one line before it can run on 0.2.x — see Compatibility & version gates.


entrypoint rules ​

typeFormatExample
asr / mt / tts / middleware / assistant / interpretation / toolfile.py:ClassNamecopilot.py:MyCopilot
Same, class name omittedfile.pyThe class name defaults to Plugin
glossaryGlossary pathterms.json
themeTheme paththeme.json
i18nDictionary pathja.json
caption_extractorScript pathextractor.js
caption_bridgeThe workshop plugin itselfUsually you don't write one, see Type overview

entrypoint must point at a file and class name that really exist — if the host cannot find them it refuses to load and explains why in the log / on the card.


Path conventions for "where do files go" ​

PurposePathNotes
Model weights<data dir>/models/<org>--<name>/Downloaded by the host; plugins must not assemble directory names themselves, use inspect_model_artifact()["target_dir"]
Plugin-private data (cache, glossary, exports)<install dir>/data/plugins/<plugin_id>/Use self.get_data_dir() / host.get_plugin_data_dir(id)
Plugin-private Python dependencies<plugin dir>/libs/ or vendor/The host injects sys.path automatically, see Runtime environment & red lines
Private binaries (llama-server etc.)<plugin dir>/bin/ and the likeOr just use Host runtimes

TransBox — empowering borderless cross-language communication for everyone