List your repository on Maru
Add one file, .maru/listing.json, to a plugin or firmware repository so Maru lists it under your name, with your README, screenshots and release downloads. What the file does, every field, how to publish it yourself, and how Maru Desktop installs a plugin built with another framework.
Add one file to your repository, .maru/listing.json, and Maru lists your plugin or firmware under your GitHub name, with your README and screenshots. You keep your code, releases and downloads where they are. Maru reads the file, links to your releases, and keeps stars and versions current.
You don't need to build anything with Maru. The file works for any plugin (VST3, CLAP, AU, LV2 and others), whether you publish its source or only its release files, and for firmware for a music device. Maru can list a repository without you having a Maru account, for example after it proposes the file to your project. To publish the listing yourself and manage it, you sign in to Maru with the GitHub account that owns the repository.
In the Help Center: List a plugin built with another framework for deciding between a listing and rebuilding your plugin with Maru.
What the file does, and doesn't
The file does three things:
- It asks for a name. Your listing lives at
@your-login/slug, for example/plugins/@asb2m10/dexed. The@your-loginpart always comes from the account that owns the repository, never from the file. - It lets Maru show your README and images. Without it, Maru shows only facts GitHub publishes, such as the description, licence, stars and latest release, and links to the README on GitHub.
- It tells Maru what you ship. Plugin formats, platforms and the compatibility you declare, or the devices your firmware runs on, mapped to your release files.
The file can't set an owner, a verified badge, tested compatibility or a price, and it can't make Maru build or sign your downloads. It adds no build step, dependency, telemetry or licence change.
Create the file
With the Maru CLI (a version that includes maru listing), from your repository's root folder:
maru listing init --family plugins --kind effect maru listing check
For firmware, add the exact device ID from the hardware directory:
maru listing init --family firmwares --device fm-1
init fills in only what your checkout shows: the name, your GitHub login from the origin remote, a licence it can recognise for certain, README images, and the CPU architectures a plug-in bundle or a file name shows (arm64, x64 or universal). It never replaces an existing file. Read the draft, change what's wrong, then commit it.
You can also write the file by hand. Point $schema at the published schema and your editor completes keys and flags mistakes:
{
"$schema": "https://maru.audio/schema/repository/listing/alpha.json",
"format": "maru-listing/v1",
"listings": [
{
"family": "plugins",
"slug": "tape-echo",
"name": "Tape Echo",
"summary": "A warm tape delay with wow, flutter and saturation.",
"kind": "effect",
"license": "GPL-3.0-or-later",
"readme": { "path": "README.md" },
"media": [{ "path": "docs/screenshot.png", "alt": "The main panel", "role": "cover" }],
"plugin": {
"formats": ["vst3", "clap", "au"],
"releaseAssets": [
{ "match": "TapeEcho-*-macOS.zip", "platforms": ["macos"], "formats": ["vst3", "clap", "au"] },
{ "match": "TapeEcho-*-Windows.zip", "platforms": ["windows"], "formats": ["vst3", "clap"] }
]
}
}
],
"display": { "readme": true, "media": true }
}
Fields
Only format, family and slug are required. Anything you leave out comes from GitHub, or stays unknown.
| Field | What to put |
|---|---|
format | Always "maru-listing/v1" |
listings | One entry per plugin or firmware, up to 20. A repository with several plugins, or firmware and an editor, has several entries |
family | plugins or firmwares |
slug | The name in your address: 2 to 80 lowercase letters, digits and single hyphens |
path | The subfolder for this entry, when the repository holds several |
name, summary | Up to 80 and 200 characters, on one line |
kind | Plugins: instrument, effect, midi-tool, app or game. Firmwares: firmware, on-device-app, controller-app, editor, daw-integration, source-release or sound-content |
tags | Up to 12 lowercase words, such as delay |
license | An SPDX expression, such as MIT or GPL-3.0-or-later, or LicenseRef- and a name for your own licence. Shown beside the licence GitHub detects |
readme | path of the README to show, and optionally "section": "maru" |
media | Up to 12 images, as repository paths or HTTPS links, each with alt text and a role of cover, screenshot or demo |
video | One HTTPS link to a demo |
links | HTTPS links: homepage, documentation, support, donate |
credits | People to credit, by GitHub login, with a role: owner, maintainer, author, contributor, porter or designer |
basedOn | Projects this one forks, ports or was inspired by: { "repository": "github:owner/repo", "relation": "fork" } |
plugin | formats and platforms you ship, and the plugin fields below |
plugin.framework | What the plugin is built with: juce, iplug2, dpf, cmajor, faust, rust or other. Shown as a credit, such as "Built with JUCE" |
plugin.compatibility | Per platform, such as macos or windows: minVersion (11, 11.0 or 10.15.7), architectures (arm64, x64, universal) and signing (unsigned or signed, or notarized on macOS) |
plugin.hosts | Up to 12 DAWs: name, optional version, a status of tested, reported or known-issue, and an optional one-line note |
plugin.install | method: archive (unzip and copy the bundles), installer (your pkg, dmg, exe or msi), download (a plain file) or build-from-source. Optional HTTPS url, and notes in one paragraph of up to 400 characters |
plugin.releaseAssets | Maps release file names to what they hold: match (* matches any text, such as a version), platforms, formats, and optionally architectures (left out means unknown, not universal), a minVersion for that file and a kind |
plugin.releaseAssets[].kind | bundle-archive (an archive of plug-in bundles, the only kind Maru Desktop installs, as a .zip), installer, source or other. Left out, .zip and .tar.gz files count as bundle archives, and .pkg, .dmg, .exe and .msi files as installers |
plugin.releases | Which GitHub releases count: channel stable (the default) or all, and a tagPattern such as v*. A GitHub prerelease is always a beta |
firmware | devices (device ID, optional board revision and release file pattern) and install (author-installer, download, build-from-source or maru-browser, with an optional HTTPS link) |
display | readme, media and mirror, each true or false. Leave out what you don't allow |
Choose what Maru shows
display is your permission, and it defaults to nothing:
"readme": truelets Maru show your README on your listing. Raw HTML in it doesn't run, and images in it aren't shown unless you list them inmedia."media": truelets Maru show the images inmedia."mirror": truelets Maru keep its own copy of those images, so your page doesn't depend on GitHub's image hosting. Leave it out and Maru links to your copies.
To show only part of your README, wrap it in markers and add "section": "maru":
<!-- maru:start --> Tape Echo is a warm tape delay with wow, flutter and saturation. <!-- maru:end -->
Maru reads the README and images at the exact commit it checked, so a later push doesn't change your page until Maru reads the repository again. Showing your README isn't permission to redistribute your release files: download links go to your releases.
If something in the file is wrong
Maru keeps what it can use. An unknown field, or a field with a bad value, is ignored and the rest of the entry still counts. Only a file that isn't valid JSON, or has no valid entry, is ignored entirely, and the listing then shows GitHub facts only. maru listing check reports the same problems Maru would.
If your slug is already taken under your name, Maru doesn't overwrite the other entry. Choose another slug.
Plugins built with other frameworks
A plugin you build with JUCE, iPlug2, DPF or your own code can be listed with its binaries, from a repository that holds only release files. Its page shows a download for each platform, the compatibility you declare and how to install it, and people with Maru Desktop can install it and receive your new releases as updates.
Maru doesn't review a listed plugin's source, and doesn't build, sign or test it. Its page and Maru Desktop say so: the files are a community release from your GitHub repository, and people download and install them at their own risk. The Terms cover work other people publish on Maru. Clear install notes and an accurate signing state help people decide whether to install it.
Take Glass Hall, an example reverb built with JUCE and given away without its source. Its repository, your-login/glass-hall-releases, holds a README, screenshots in images/, a licence and a changelog. Its GitHub release v1.0.0 has one file, GlassHall-1.0.0-macOS-arm64.zip, which unzips to Glass Hall.vst3 and Glass Hall.app. It runs on Apple Silicon Macs with macOS 11 or later, isn't signed, and has been tested in Ableton Live 12.
What to add
Add .maru/listing.json and nothing else. The README and screenshots are already in the repository; the file points at them and allows Maru to show them. Draft it with maru listing init --family plugins --kind effect, then complete it by hand:
{
"$schema": "https://maru.audio/schema/repository/listing/alpha.json",
"format": "maru-listing/v1",
"listings": [
{
"family": "plugins",
"slug": "glass-hall",
"name": "Glass Hall",
"summary": "A bright hall reverb with a freeze switch and a shimmer octave.",
"kind": "effect",
"tags": ["reverb", "shimmer"],
"license": "LicenseRef-GlassHall-Freeware",
"readme": { "path": "README.md" },
"media": [
{ "path": "images/panel.png", "alt": "The Glass Hall panel with its decay and shimmer controls", "role": "cover" },
{ "path": "images/freeze.png", "alt": "The freeze switch holding a chord", "role": "screenshot" }
],
"links": { "support": "https://github.com/your-login/glass-hall-releases/issues" },
"credits": [{ "github": "your-login", "role": "author" }],
"plugin": {
"framework": "juce",
"formats": ["vst3", "standalone"],
"platforms": ["macos"],
"compatibility": {
"macos": { "minVersion": "11.0", "architectures": ["arm64"], "signing": "unsigned" }
},
"hosts": [{ "name": "Ableton Live", "version": "12", "status": "tested" }],
"install": {
"method": "archive",
"notes": "Unzip, move the VST3 to ~/Library/Audio/Plug-Ins/VST3 and the app to Applications. The build isn't notarized: allow it in System Settings, Privacy & Security."
},
"releaseAssets": [
{
"match": "GlassHall-*-macOS-arm64.zip",
"platforms": ["macos"],
"architectures": ["arm64"],
"formats": ["vst3", "standalone"]
}
]
}
}
],
"display": { "readme": true, "media": true }
}
The * in match stands for the version, so the same pattern names the file in every later release. Run maru listing check and commit the file.
Publish it
Publishing needs a Maru account with the GitHub account that owns the repository linked at Connections. That link is what makes the listing yours. For a repository owned by a GitHub organization, the file's credits on the default branch must name your GitHub login with the role owner or maintainer; committing the file there shows you can write to the repository. The organization's community page then owns the listing, and you manage it.
Then use one of these:
- Website: open Repository listings, choose Add a repository and enter
your-login/glass-hall-releases. The result lists every problem the file had. - CLI: run
maru loginonce, thenmaru listing publishfrom your checkout. It reads the file first and stops, sending nothing, when the file is missing or can't be read; problems Maru would ignore are only noted, andmaru listing checklists them. It finds the repository from youroriginremote, and prints your listing's page and the releases Maru read. - CI: an access token with only the
listings:publishpermission, saved as theMARU_TOKENsecret, and a workflow that runsmaru listing publisheach time you publish a GitHub release. Publish a repository listing from CI has the workflow.
Maru reads the repository at its current commit, records the listing, and records your releases: up to the 20 newest, each file with its size and the SHA-256 checksum GitHub recorded for it. Drafts are never read. Nothing is uploaded to Maru, and download links go to your GitHub releases.
What your page shows
Glass Hall's page is at /plugins/@your-login/glass-hall. Beside the README and screenshots it shows:
- Downloads. A notice that the files are a community release, downloaded at the reader's own risk, then the newest stable release first, with a row for each file a
releaseAssetspattern matched: its name, platform, architectures, formats, minimum system version, size and SHA-256, and a link to the file on GitHub. Files no pattern matched are listed under other files, and older releases are collapsed. Prereleases are betas and are shown only whenreleases.channelisall. - Compatibility, declared by the author. Your
compatibilityandhosts, with the signing state in plain words: an unsigned or un-notarized macOS build says that macOS asks the person to allow it the first time. - Install. Your
installmethod and notes, and a link to your README on GitHub. - Open in Maru Desktop. Shown when a release has a bundle archive for macOS, Windows or Linux, with a line saying that Desktop marks it as a community release Maru hasn't reviewed.
The header shows your licence and, with framework set, "Built with JUCE".
What Maru Desktop does
Maru Desktop installs a bundle archive from your release, and only that kind of file: a .zip of plug-in bundles, on a Mac. It offers Install when the archive matches the Mac's architecture, or is universal. For every other file, and on Windows and Linux, it offers the download from GitHub and your install instructions.
Desktop labels the plug-in a community release on its page, and a community release not reviewed by Maru in the Library, the installed plug-ins and updates. Before anything downloads, Desktop says the plug-in comes from your GitHub release, not from Maru, that Maru hasn't reviewed, built or signed it and can't guarantee it's safe, and repeats the signing state you declared. The person confirms, and an update asks again. Desktop then downloads the archive, up to 512 MiB, and installs it only when it matches the SHA-256 GitHub recorded. A release file without a checksum on GitHub can be downloaded, not installed.
Desktop opens the archive without running anything in it and shows the .vst3, .component, .clap and .app bundles it will install, and where. It installs them in the usual plug-in folders and can remove them later like any other plug-in. Other files in the archive are named and left out.
Desktop never signs your build and never removes the quarantine mark macOS adds to downloads. An unsigned build still goes through macOS's own prompt the first time it opens, which is why your install notes should say how to allow it.
How updates reach people
A new GitHub release reaches your page the next time Maru reads the repository: when maru listing publish runs, which the CI workflow does for each release, or when you choose Read again on Repository listings. Edits to the file arrive the same way, and a release you delete from GitHub disappears from the page.
When the newest stable release has an archive for their computer, Maru Desktop offers people who installed your plugin an update to that version. Updates never install on their own.
What a listing can't do
A plugin listed this way has no browser preview, can't be loaded inside other Maru instruments, effects and racks, has no verified or tested badge, and has no downloads that Maru builds or signs. Those come from building the plugin with the Maru framework and publishing it on Maru.
Go further: build it with Maru
You can port a listed plugin to the Maru framework whenever you're ready, and the listing keeps working while you do. Building it with Maru adds:
- A web demo. People play the plugin on its page, in the browser, before they download anything.
- Recomposition. Other people can put it in a live rack or load it inside another module, with its controls and presets.
- Remixing, when you release it open source. People can fork the source and publish their own version, which keeps your credit. See the Maru Remix License.
- Automated builds. Maru builds the plug-in for each DAW format and operating system it supports, on its servers or in your CI, so you don't keep a build machine for each one. Pricing lists the plans with hosted builds, and Build and publish a module in CI covers your own runners.
If the plugin relies on unusual technology, such as a custom machine-learning model, a video feed or other demanding processing, the Maru team works with you to sort it out. Contact Maru with what the plugin does and what it depends on.
To start, Porting an existing plugin maps a JUCE plugin onto a Maru module, the Quickstart sets up a local project, and Choosing Maru compares the approach with other frameworks.
Your address and your account
Your listing's address uses a Maru profile for your GitHub account, or a community page for a GitHub organization. Maru creates it the first time it lists one of your repositories, and uses your login as the handle when that's free. Until the owner has a handle, the page is at /plugins/id/ followed by the listing's ID, the address maru listing publish and Repository listings show; that address keeps working afterwards. Renaming the repository keeps the listing. Transferring it to another account moves nothing until the new owner asks.
The first time you publish a listing while signed in with the same GitHub account, Maru moves the listings it already made for that account into yours, and their old addresses keep working. A repository whose listing belongs to another Maru account can't be published from yours; contact Maru if that listing is wrong.
Change or remove a listing
Edit and commit the file. Maru picks up the change the next time it reads the repository. To stop Maru showing your README and images, set display to false or delete the file. If you manage the listing, Repository listings also lets you hide it, show it again or withdraw it. To have the listing taken down entirely, contact Maru from the email on your GitHub profile, or ask in a GitHub issue on your repository that mentions the listing.
If Maru opened a pull request
Maru sometimes proposes this file to projects it would like to list. The pull request adds .maru/listing.json and nothing else, and links to the page your project would get. Merging it agrees to the name and the display permission in the file; you can edit the file before or after merging. Closing it is a fine answer: Maru records that and never opens another one on your repository.