Layout & mod.json
This page is the single authoritative table of
mod.jsonfields. 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_extensionsRules:
- One MOD = one folder,
idglobally unique; the directory name should ideally matchidbut 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 intodata/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
| Field | Required | Default | Notes |
|---|---|---|---|
id | Yes | — | Globally unique, shaped like myteam.mt.deeplx. A missing id is rejected outright. The reserved official segments builtin.* / community.* / workshop.* may not be used |
name | Recommended | Untitled MOD | Display name |
version | Recommended | 1.0.0 | Semantic 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) |
author | Recommended | Unknown author | — |
description | No | "" | Hub blurb |
type | Recommended | glossary | See Type overview |
entrypoint | Type-dependent | "" | See "entrypoint rules" below |
icon | No | Auto-detected | svg / png / webp / jpg |
preview_image | No | — | Relative path of the hub preview image |
tags | No | [] | 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_url | No | "" | External link to official docs (shown on the card) |
target_app_version | Yes (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_version | No | 1.0.0 | Minimum compatible client version. 1.0.0 = no restriction; see Compatibility & version gates |
tier | No | free | free / pro / community |
supported_langs | No | [] | Source language capability list; used for source-language clamping and card display. MT target languages belong in target_langs |
target_langs | No (recommended for MT) | Falls back to supported_langs | Translation 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 |
aliases | No | [] | Short-name aliases (e.g. ["cool"]); the settings page / routing resolves them back to the full id |
requires_hf | No | Inferred from tags/id | false = pure API/cloud, startup may skip the transformers warm-up; true = needs HF |
requires_cuda | No | — | false = does not hard-require NVIDIA (AMD ROCm / Vulkan / CPU are all fine) → the host stops showing the "CUDA required" red box |
model_artifacts | No | [] | Local model artifact declarations, see Model artifacts |
requires_plugins | No | [] | Prerequisite plugin dependencies (≤ 8), see Prerequisite plugins |
requires_runtime | No | [] | Host runtime dependencies (≤ 4), see Host runtimes |
capabilities | No | {} | Engine capability declaration (voice list / cloning / removal / native speed), see Capability declaration |
config_schema | No | [] | Declarative config form, see config_schema |
ui_extensions | No | {} | Slot → QML file mapping, see UI slots |
hotkeys | No | [] | Declarative global hotkeys, see Global hotkeys |
host_events | No | [] | Host event names to receive (["*"] = all), see Event bus |
permissions | No | [] | Capability declaration strings (net / clipboard / hotkey / window…), used for hub display and future gates |
supports_glossary | No | Inferred from type/tags/id | true = natively consumes the glossary / hotwords |
style_layer | No | full (theme only) | full / material / typography / effects |
has_settings_tab / tab_id / tab_title | No | — | Standalone settings tab, see Custom settings view |
language_code / language_name | No | — | i18n only |
enabled | No | false for theme/i18n, true otherwise | Initial enabled state (the user's switch overrides it) |
source_lang / target_lang | No | "" | 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_versionis the only field that makes your plugin uninstallable when omitted. Without it: dropping the folder intoextensions/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
| type | Format | Example |
|---|---|---|
asr / mt / tts / middleware / assistant / interpretation / tool | file.py:ClassName | copilot.py:MyCopilot |
| Same, class name omitted | file.py | The class name defaults to Plugin |
glossary | Glossary path | terms.json |
theme | Theme path | theme.json |
i18n | Dictionary path | ja.json |
caption_extractor | Script path | extractor.js |
caption_bridge | The workshop plugin itself | Usually 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"
| Purpose | Path | Notes |
|---|---|---|
| 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 like | Or just use Host runtimes |
