Skip to content

For developers

Publish an extension

Extensions are published from the CLI with a user token. The registry validates the version, refuses to overwrite history, and serves the archive to anyone entitled to it.

Terminal
# install the CLI $ npm install -g module-registry-client-lib # publish to the stable channel $ msc publish --modulePath=./dist \ --userToken=$USER_TOKEN --tag=main

What your package must contain

These fields drive everything a visitor sees on the marketplace — name, summary, category, price and whether the extension is part of Premium.

Required and optional package.json fields
Field Required Used for
appId Required Unique id in the registry and in every install command
appName Required The name shown on the card and detail page
version Required Semantic version — must be higher than the latest on the tag
description Required The long description, taken from README.md
changelog Required The release history, taken from CHANGELOG.md
category Required Which category the extension is filed under
appTags Optional Filter chips; falls back to keywords
price Optional Price in USDT for paid extensions
forSale Optional Whether the extension is sold at all
isAvailableBySubscription Optional Include the extension in the Premium collection
icon Optional Card and detail icon — icon.svg in the root wins over this
appSupport Optional Issue tracker link shown in the Support block
mmDependencies Optional Other registry extensions this one needs

README.md and CHANGELOG.md must exist in the module root. If you ship a settings directory, every JSON file needs a key and a type — and the key has to be unique across every extension on the platform.

Publishing rules

  • 1

    Versions are semantic and final

    Only valid semver is accepted, and an existing version is never rewritten.

  • 2

    Each tag only moves forward

    Within a tag you can only publish higher than the current latest. To ship something lower, publish it under a different tag.

  • 3

    main is the default channel

    Missing or invalid tags fall back to main. Use staging for pre-release builds — a staging build can later be promoted to main at the same version.

How users install your builds

The channel decides which version latest resolves to.

Stable — the default
msc install --appId=your-extension
Staging, falling back to stable
msc install --appId=your-extension --channel=staging
Highest version across every channel
msc install --appId=your-extension --channel=any
An exact version
msc install --appId=your-extension --version=1.4.2

Free, paid, or part of Premium

Two flags in your package.json decide how your extension is sold. They are not exclusive — an extension can be sold outright and belong to Premium at the same time.

Free

No license needed

Leave forSale off. Anyone can install it without a token.

Paid

One-time purchase

Set forSale and price. Buyers get permanent access bound to their license address.

Premium

Included in the subscription

Set isAvailableBySubscription. Your extension joins the Premium collection and installs for every active subscriber.

Get a publisher token

Publishing needs a user token tied to your account. Write to us with the appId you want to claim and what the extension does.