Skip to content

Packaging & size limit ​

A plugin is just a folder plus a mod.json. Packaging = zipping the whole folder.


What goes into the package ​

The root of the zip must be mod.json directly (no extra wrapping folder):

text
my_mod.zip
├── mod.json          ← at the root
├── my_mod.py
├── locales/
├── icon.svg
└── *.qml

The client's built-in export feature packages by this rule; when packaging by hand, take care not to zip an outer folder in as well.


Size limit: 20 MB (hard limit) ​

StageLimit
Client pre-check before upload20 MB (anything bigger is stopped locally, not a single byte is sent)
Server (Pages Function)20 MB

The Plugin Hub runs on a Cloudflare Pages Function, and packages from 45 MB up get cut off mid-upload by the platform (the client only sees a write failure, with no useful hint) — so we block up front at 20 MB.

What to do with big data ​

ThingHow to distribute it
Model weights (hundreds of MB to a few GB)model_artifacts in mod.json → the host downloads them from HF / ModelScope into the user data directory. See Model artifacts
Native runtimes (.dll / .exe, tens of MB)requires_runtime → the host downloads, verifies and unpacks on demand. See Host runtimes
Lightweight Python dependenciesShip them in libs/ or vendor/ with the package (see Runtime environment)
Tens of MB of your own binary and there is no matching official runtimeContact the official team for a separate distribution channel (do not stuff it into the .tbmod)

Lesson from the field: an author once packed an 88 MB llama runtime into a package and the upload was bound to fail. The runtime components we have today exist for exactly this scenario.


Version number ​

  • version in mod.json must be a semantic x.y.z version.
  • It is required when publishing to the Plugin Hub, and a new version must be higher than the highest online version (you can edit it directly on the publish page).
  • Local loading accepts it being absent (defaults to 1.0.0).
  • version (your own release number) and target_app_version (the client generation you adapt to, must be 0.2) are two different things — see Compatibility & version gates.

Pre-packaging self-check ​

  • [ ] The zip root is mod.json directly (not my_mod/mod.json)
  • [ ] mod.json declares "target_app_version": "0.2" (without it the plugin cannot be installed, see Compatibility & version gates)
  • [ ] id is globally unique and the author segment is not a reserved name (transbox / official / builtin / community / example / workshop / steam / system / admin / root / support / web / test / tbmod)
  • [ ] version is x.y.z and higher than the highest online version
  • [ ] The file entrypoint points to and the class name really exist
  • [ ] The package contains no __pycache__ / .git / temporary files
  • [ ] Total size < 20 MB; no big binaries or weights
  • [ ] locales/ has both the Chinese and the English file (see i18n)
  • [ ] The icon is a vector SVG, not Emoji / characters

TransBox — empowering borderless cross-language communication for everyone