Nuvaka › Developer docs › In-app store (addons)

In-app store: addons

An extension can open its own addon store: language and theme packs for a code editor, level packs for a game, commands for a tool. Other developers publish the addons; users install them from inside the host app. The Nuvaka store's safeguards (signing, scanning, review, yanking) apply to addons exactly the same way.

Note: The SDK side (nuvaka.addons) arrives with Nuvaka 0.3.1. Store and publishing rules already apply.

Terms

  • Host: an extension that accepts addons. Its manifest has an addons field.
  • Addon: a Nuvaka package whose manifest has addonOf. There are two kinds:
    • Data addon ("addonKind": "data"): runs no code. It is made of JSON, text and images that the host reads and interprets.
    • Code addon ("addonKind": "code"): a normal extension with its own page or background script. The host calls the functions it exposes.

Host manifest

"addons": {
  "kinds": ["data", "code"],
  "open": true,
  "schema": "codeeditor.addon/1",
  "maxSizeMB": 5
}
FieldRule
kindsrequired; accepted kinds: "data", "code" or both
openrequired; true lets anyone publish addons, false only the host's publisher
schemaoptional; name of the format data addons follow (e.g. codeeditor.addon/1). Documenting it is up to the host.
maxSizeMBoptional; 1–20. Maximum addon package size (default 20).

If the addons field is removed or open is turned off, published addons stay; new ones are refused (addons_not_accepted / addons_closed).

Addon manifest

{
  "id": "rust-lang-pack",
  "name": { "tr": "Rust dil paketi", "en": "Rust language pack" },
  "version": "1.0.0",
  "addonOf": "code-editor",
  "addonKind": "data",
  "minAppVersion": "0.3.1"
}
  • addonOf: the host's id. It cannot change after the first publish. A published normal extension cannot later become an addon.
  • addonKind: data or code; must be in the host's kinds (otherwise addon_kind_not_accepted).

Data addon rules

  • These fields are forbidden: entry, pages, permissions, storage, shared, triggers, settings, contributes, workers, addons, dependencies.
  • Only these file types: json, txt, md, png, jpg, jpeg, webp, svg. SVGs may not contain <script>, on*= attributes, foreignObject, javascript:, or iframe/embed/object.
  • At most 20 MB (or the host's maxSizeMB; beyond it addon_too_large) and 500 files.

Code addon rules

  • Must have a required extends dependency on the host (Dependencies): { "id": "<host>", "version": "^x.y.z", "kind": "extends" }.
  • Permissions are not inherited: a code addon requests its own permissions and the user approves them separately.
  • All normal extension rules (lint, scan, review) apply.

Platforms

An addon's platforms set must be within the host's (Platform compatibility); otherwise platform_exceeds_dependency.

Getting started with the CLI

nuvaka-ext init rust-lang-pack --addon-of code-editor --kind data
nuvaka-ext init my-formatter --addon-of code-editor --kind code

Publish as usual with nuvaka-ext publish.

Addons in the store

  • Addons don't appear in the Nuvaka store's main lists. They appear in the host's own store tab and on publisher pages.
  • GET /api/ext/v1/store?addonOf=<host>: a host's addons. Search, sorting and paging work the same.
  • The host's detail returns addons: { kinds, open, schema, maxSizeMB, count }.

Install and uninstall

  • An addon installs only if the host is installed; otherwise the server returns 409 host_required with { host }.
  • The user always confirms installs: even when the host calls nuvaka.addons.install, Nuvaka shows its own confirmation window.
  • When the host is uninstalled, Nuvaka offers to remove its addons too. Addon data is kept for 30 days.

Host API: nuvaka.addons

Only a host (an extension with an addons field) can make these calls. store always lists the caller's own addon store; an app can't see another app's store. call doesn't give the host's permissions to the addon.

CallDescription
list()Installed addons: [{ id, version, kind, name, files }]
read(id, path)A file from a data addon; Uint8Array
readText(id, path) / readJson(id, path)Same, as text or parsed JSON
call(id, method, arg)Calls a function a code addon exposes
store(query)Returns this host's addon store list
install(id)Starts an install; Nuvaka shows the confirmation. cancelled if the user declines.
uninstall(id)Starts an uninstall (confirmed)
onChanged(cb)Called when an addon is installed, updated or removed
for (const a of await nuvaka.addons.list()) {
  if (a.kind !== 'data') continue
  const meta = await nuvaka.addons.readJson(a.id, 'addon.json')
  registerLanguages(meta.languages)
}
nuvaka.addons.onChanged(() => location.reload())

Example schema: codeeditor.addon/1

Nuvaka's code editor accepts language, theme and snippet addons. A data addon has addon.json at its root:

{
  "schema": "codeeditor.addon/1",
  "languages": [
    { "id": "rust", "extensions": [".rs"], "aliases": ["Rust"],
      "monarch": "rust.monarch.json", "configuration": "rust.config.json" }
  ],
  "themes": [
    { "id": "ember", "label": { "tr": "Kor", "en": "Ember" }, "base": "vs-dark", "file": "ember.theme.json" }
  ],
  "snippets": [{ "language": "rust", "file": "rust.snippets.json" }]
}
  • Theme file: { "inherit": true, "rules": [...], "colors": { ... } }.
  • Snippets use the VS Code format (prefix, body, description).
  • A code addon adds commands:
nuvaka.expose('codeeditor.commands', () => [{ id: 'sort-lines', title: 'Sort lines' }])
nuvaka.expose('codeeditor.run', ({ command, text, selection, language, fileName }) => {
  const sorted = text.split('\n').sort().join('\n')
  return { text: sorted, replace: 'selection', message: 'Sorted' }
})

replace: 'selection' or 'document'. message is optional and shows in the status bar.

Error codes

CodeMeaning
addons_not_acceptedThe target extension doesn't accept addons
addon_kind_not_acceptedThis kind (data/code) is not accepted
addons_closedopen: false; only the host's publisher can publish
addon_too_largePackage exceeds maxSizeMB
platform_exceeds_dependencyThe addon's platforms exceed the host's
host_required(409) Install the host first
"addonOf değiştirilemez"A published addon's host can't change
"yayındaki uzantı eklentiye dönüştürülemez"A published normal extension can't become an addon; publish under a new id

Nuvaka Apps API v1 · last updated 2026-09-28