Skip to content

Publishing your mod

Zephyr ships with a curated community registry called Zephyr Mods. If you wrote a mod for a game Zephyr supports, you can submit it there and it will appear in everyone's Browse page, alongside Thunderstore and CurseForge results.

No Thunderstore account, no upload process. The registry is a plain GitHub repo and your binaries stay on your own GitHub Releases.

How it works

Each entry in Prismo-Studio/zephyr-mods is a folder under mods/<game>/<your-github-username>/<mod-slug>/ with:

  • mod.json -- metadata (name, description, repository, dependencies)
  • icon.png -- 256x256 icon
  • README.md -- shown in Zephyr's mod detail panel
  • CHANGELOG.md -- release notes
  • versions/<x.y.z>.json -- one file per version, pointing at a GitHub Release asset with its SHA-256

Zephyr fetches the registry, downloads the asset from GitHub when a user installs, verifies the hash, and refuses to install on mismatch. The bytes you sign off on at PR review are exactly what users get.

Submit a mod

You need Node.js and pnpm installed. Fork the registry, then:

bash
git clone https://github.com/<your-username>/zephyr-mods.git
cd zephyr-mods
pnpm install
pnpm new-mod

The wizard asks a few questions, fetches your repo's README, icon, and latest GitHub release automatically, computes the SHA-256, and writes everything in the right place.

bash
git checkout -b add-<mod-slug>
git add mods/
git commit -m "Add <mod-slug>"
git push -u origin add-<mod-slug>

Open a PR against Prismo-Studio/zephyr-mods. CI validates the schema, checks the URL points at your declared GitHub repo's releases, and verifies you (the PR author) own the folder. Once merged, the registry rebuilds within a minute and Zephyr picks up your mod within five.

Publish a new version

When you cut a new GitHub Release for your mod:

bash
pnpm new-version <game>/<your-username>/<mod-slug>
# example
pnpm new-version repo/johndoe/better-inventory

The wizard pulls the latest release from your source repo, computes the new hash, updates mod.json, writes a new versions/x.y.z.json, and appends to CHANGELOG.md. Open a PR, merge, done.

Users get a version-switch dropdown in Zephyr that lets them roll forward or back without uninstalling.

Distribution formats

The release asset can be:

  • A .dll -- single-file BepInEx plugin. Goes to BepInEx/plugins/<your-mod>/<your-mod>.dll.
  • A .zip -- multi-file mod with assets, configs, libs. Zephyr unzips it via the BepInEx subdir installer (plugins/, patchers/, monomod/, core/, config/).

If your zip ships a manifest.json at the root (Thunderstore format), Zephyr will read name/author/version/dependencies from it.

Security model

  • Asset URLs must point at GitHub Releases of the declared repository. Anything else is rejected by CI.
  • Every version file ships a SHA-256. Zephyr verifies the hash after download and refuses to install on mismatch.
  • A mod folder under mods/<game>/<author>/... can only be modified by PRs from <author> or Prismo-Studio admins. Enforced by CI.

This means a compromised maintainer account can't backdoor someone else's mod, and bytes that pass review are bytes that ship.

Dependencies

Other mods (Thunderstore-style identifiers) can be declared in mod.json:

json
"dependencies": [
  "BepInEx-BepInExPack-5.4.2100"
]

When a user installs your mod, Zephyr resolves these against Thunderstore and installs them alongside. Cross-source dependency on another Zephyr Mods entry isn't supported yet.

Manual edits

Anything the wizard does, you can do by hand. Run pnpm validate before pushing. CI runs the same script.

Where to ask for help

Discord is the fastest way. Bugs in the registry CI go on issues.

Released under GPL-3.0.