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-login part 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:

bash
maru listing init --family plugins --kind effect
maru listing check

For firmware, add the exact device ID from the hardware directory:

bash
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:

json
{
  "$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.

FieldWhat to put
formatAlways "maru-listing/v1"
listingsOne entry per plugin or firmware, up to 20. A repository with several plugins, or firmware and an editor, has several entries
familyplugins or firmwares
slugThe name in your address: 2 to 80 lowercase letters, digits and single hyphens
pathThe subfolder for this entry, when the repository holds several
name, summaryUp to 80 and 200 characters, on one line
kindPlugins: instrument, effect, midi-tool, app or game. Firmwares: firmware, on-device-app, controller-app, editor, daw-integration, source-release or sound-content
tagsUp to 12 lowercase words, such as delay
licenseAn 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
readmepath of the README to show, and optionally "section": "maru"
mediaUp to 12 images, as repository paths or HTTPS links, each with alt text and a role of cover, screenshot or demo
videoOne HTTPS link to a demo
linksHTTPS links: homepage, documentation, support, donate
creditsPeople to credit, by GitHub login, with a role: owner, maintainer, author, contributor, porter or designer
basedOnProjects this one forks, ports or was inspired by: { "repository": "github:owner/repo", "relation": "fork" }
pluginformats and platforms you ship, and the plugin fields below
plugin.frameworkWhat the plugin is built with: juce, iplug2, dpf, cmajor, faust, rust or other. Shown as a credit, such as "Built with JUCE"
plugin.compatibilityPer 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.hostsUp to 12 DAWs: name, optional version, a status of tested, reported or known-issue, and an optional one-line note
plugin.installmethod: 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.releaseAssetsMaps 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[].kindbundle-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.releasesWhich GitHub releases count: channel stable (the default) or all, and a tagPattern such as v*. A GitHub prerelease is always a beta
firmwaredevices (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)
displayreadme, 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": true lets 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 in media.
  • "media": true lets Maru show the images in media.
  • "mirror": true lets 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":

markdown
<!-- 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:

json
{
  "$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 login once, then maru listing publish from 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, and maru listing check lists them. It finds the repository from your origin remote, and prints your listing's page and the releases Maru read.
  • CI: an access token with only the listings:publish permission, saved as the MARU_TOKEN secret, and a workflow that runs maru listing publish each 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 releaseAssets pattern 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 when releases.channel is all.
  • Compatibility, declared by the author. Your compatibility and hosts, 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 install method 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.