Publishing guidelines

Want your widget in the gallery? Submit it through the submission form. We review every widget by hand — these are the things we check, so getting them right means a faster approval.

Requirements

  • A valid manifest.json. Correct manifestVersion, a unique reverse-domain id, plus name, version, entry and defaultSize. See the manifest reference.
  • The entry HTML loads cleanly. No errors in the console, no missing files.
  • Request only the permissions you use. Unused permissions are a reason to send a widget back.
  • Include a clear preview image. Reference it with preview in the manifest so people can see what they’re installing.
  • Keep it self-contained. Bundle every asset. Remote code, analytics and network calls aren’t discouraged — they’re blocked outright, so a widget that reaches for a CDN font or a remote image simply renders without it.
  • Handle the empty state. Show something sensible when nothing is playing (track === null).

Sign it before you package it

A .nepget bundle carries its own signature, and NepTunes refuses to install a bundle whose signature doesn’t check out — so signing isn’t a publishing formality, it’s part of building the widget.

The tool is widget-tools.mjs: one Node script, built-ins only, nothing to install. Grab it and run it next to your bundle:

curl -O https://neptunesmac.app/widget-tools.mjs

# Once per author. Writes the private half to .keys/my-widget-author.pem
# (mode 0600, never leaves your machine) and the public half to
# public-keys/my-widget-author.pub.
node widget-tools.mjs keygen my-widget-author

# After every content change — including a version bump.
node widget-tools.mjs embed-sign MyWidget.nepget --key .keys/my-widget-author.pem
node widget-tools.mjs embed-verify MyWidget.nepget

See Updates & signing for what the signature covers and how the downgrade ratchet behaves.

embed-sign writes bundle.sig into the bundle and fills authorPublicKey into your manifest.json. Submit the bundle with bundle.sig inside it.

Packaging

Zip the .nepget folder so the archive contains the bundle (manifest at the top level, bundle.sig beside it). Keep the whole thing under 8 MB — that’s the upload limit on the submission form.

Registering your id

A widget id belongs to exactly one author key. Our packaging tooling keeps a widget id registry mapping each id to the key allowed to publish under it, and if a bundle ever shows up signed with a key that isn’t the registered one, publishing aborts.

So, alongside the bundle, send us the base64 public key printed by keygen (the contents of the .pub file, public-keys/my-widget-author.pub). Never send the private half — we don’t need it and can’t accept it.

What we can’t do yet: the packager can only sign with private keys we hold, so it cannot publish your bundle under your key. Today an accepted third-party submission goes into the gallery re-signed with the first-party NepTunes key, and its id is registered against that key. Your signature is still worth having — it proves the bundle we reviewed is the one you sent — but it isn’t the key your gallery users will see pinned. Passing an author-signed bundle straight through is pipeline work still to be done.

Signing & updates

Once your widget is in the gallery, versions you ship afterwards are delivered through a signed update feed on top of your own bundle signature: the feed is signed with a key built into the app, each download is checked against its recorded hash and signature, and the user confirms every install. Keep your id stable, bump your version, keep signing with the same key — a different key turns every user’s update into a re-consent prompt, and an unsigned bundle for an id that already installed signed is refused outright. See Updates & signing for the full picture.

What happens next

Submit via /widgets/submit. We’ll email you about the review. Once a widget is approved, it appears in the gallery with credit to you as the author.

← DebuggingUpdates & signing →