Repository Structure
To keep repositories clean and organised, OpenMods reads everything it needs from a single .openmods folder at the root of your repo. One manifest file (openmods.json) describes your gallery, links, FAQ, thumbnail, and install rules.
folder The .openmods Folder
Drop a manifest and any media you reference into .openmods/:
├── .openmods/
│ ├── openmods.json // Manifest: links, media, faq, thumbnail, install
│ └── media/ // (Optional) Gallery assets (png, jpg, mp4, etc.)
├── README.md // Standard GitHub readme (rendered on your mod page)
└── * // Your actual mod source code
One file, every sync
openmods.json is the source of truth. Every refresh rebuilds your links, FAQ, gallery, and thumbnail from what the file says — dashboard tweaks are overwritten by the next sync, so commit your changes.
data_object openmods.json — full example
Every top-level field is optional. Omit a section and that area of your mod page stays untouched.
Forgiving parser
JSON comments (//) and trailing commas are accepted, so you can leave notes for collaborators inline.
link
links — sidebar links
A list of external links rendered as a styled sidebar section.
label
string · requiredVisible button text.
url
string · requiredDestination URL.
icon
string · optionalA Material Symbols name (e.g. chat, language) or an emoji. When omitted, OpenMods picks a sensible default for common labels like Discord / Website / Support / GitHub.
image
media & thumbnail — gallery
media is the gallery in display order. thumbnail is your mod's hero image.
url
string · requiredA filename from .openmods/media/ (e.g. cover.png) or a full https:// URL (e.g. a YouTube link). Filenames are resolved against the media folder by basename.
type
"image" | "video" · optionalInferred from the URL extension when omitted. Use video for YouTube/Vimeo embeds.
label
string · optionalCaption / alt text. Parsed but not currently rendered — use it as an organisational note.
Supported images
.png · .jpg · .jpeg · .webp · .gif
Supported videos
.mp4 · .webm
Unresolved files are skipped
If a filename isn't found in .openmods/media/, the entry is dropped from the gallery and a warning is logged. Check spelling and the file extension.
quiz
faq — questions & answers
A list of { "question", "answer" } pairs. Renders as an interactive accordion on your mod page.
extension
add-on-of — declare your mod as an add-on
Numeric mod id of the parent mod. Your mod will appear in that mod's Add-ons section, and its sidebar will show a chip pointing back at the parent.
Where to find a mod's id
Open the mod's page on OpenMods. The id is the number at the end of the URL, e.g. openmods.net/mod/42 → "add-on-of": 42.
- check_circle Omit the field → whatever you set in the dashboard stays. Use it for a soft migration.
- check_circle Set to a positive number → mod becomes an add-on of that parent.
- check_circle
Set to
null→ clears any existing parent (the mod becomes standalone). - warning Unknown ids or self-references are skipped with a warning — the rest of the manifest still applies.
account_tree
dependencies — per-release requirements
An object keyed by your mod's release tag. Each value is the list of required mods for that release, replacing whatever was previously recorded. Releases not listed are left untouched.
modId
number · requiredNumeric mod id of the required mod (same shape as add-on-of — visible in the URL of the mod's page).
release
string · optionalExact-version pin (shortcut for fromRelease == toRelease). Overrides the from/to fields when set.
fromRelease / toRelease
string · optionalInclusive lower/upper bound on acceptable releases of the required mod. Omit one for an open bound. Omit both for "latest".
Resolves to the same constraint labels you see on the mod page:
- check_circle No bounds → "latest"
- check_circle
release: "3.0.1"→ exact pin: "3.0.1" - check_circle
fromRelease: "3.0.0"→ "3.0.0+" - check_circle
toRelease: "3.5.0"→ "≤ 3.5.0" - check_circle
fromRelease+toRelease→ "3.0.0 → 3.5.0"
Inheritance still applies
A release without explicit requirements inherits from the next older release that has them — same behavior as the dashboard. Use "1.0.0": [] to explicitly clear that release's dependencies.
Strict version matching
Release tags must match exactly (case-insensitive) what GitHub shows. Unknown release keys, missing modIds, and unresolved release/fromRelease/toRelease values are skipped with a warning.
deployed_code
install — OpenMods Manager rules
Tells the OpenMods Manager desktop app how to lay your release archive into the player's game folder. Without it, the Manager extracts the archive into the game root.
path
string · optionalBase directory where archive contents land, relative to the game install root.
custom-path
object · optionalPer-file / per-folder mapping. Keys are paths inside the archive; values are destinations relative to the game root. Trailing slashes mark folder copies.
- check_circle
No
installblock → archive contents drop into the game root, skipping any bundled.openmods/folder. - check_circle
Only
path→ everything lands under that directory. - check_circle
Only
custom-path→ mapped files/folders go to their destinations; the rest drop at the game root. - check_circle
Both →
custom-pathwins for entries it covers; the rest fall underpath.
Ship openmods.json in your release
Include .openmods/openmods.json inside your release archive so the Manager can read the install rules without re-fetching the repo.
Ready to distribute your mods?
Join hundreds of other developers using OpenMods to deliver their creations to players faster.