Versions and publishing

Give a plugin a version, a sign and a color, and list it in a catalog so that it can be installed and updated from the program.

Versions

A plugin says its version with version: numbers with dots between them, such as 1.2.0. It is shown beside the plugin's name as v1.2.0. A plugin that says none is shown as having no version, and any released version counts as later than it.

const plugin: Plugin = {
  id: 'sunburst',
  name: 'Sunburst',
  version: '1.4.0',
  author: 'You',
  about: 'Rays round a middle, to insert.',
};
export default plugin;
from rassam import Plugin

plugin = Plugin('sunburst', 'Sunburst', version='1.4.0', author='You',
                about='Rays round a middle, to insert.')

Versions are compared number by number, from the left, so 1.10 is later than 1.9, and 1.2.1 is later than 1.2. A missing number counts as 0: 1.2 and 1.2.0 are the same version. A v before the numbers is let pass. Anything after a - or a + is read as one more number, so keep to plain numbers.

ChangeRaiseExample
A fix that changes nothing a user setsthe last number1.2.0 to 1.2.1
Something new that leaves projects as they arethe middle number1.2.1 to 1.3.0
A change that projects made with the old one may not survive (a key renamed, a setting removed)the first number1.3.0 to 2.0.0
Keep the id and the keys of what the plugin adds the same from one version to the next. Layers remember them: an element made by sunburst:burst is drawn by whichever version of sunburst is installed.

Plugins that depend on others

A plugin names the plugins it cannot do without in needs, by their ids. Turning it on turns those on too; one that is not installed is installed from the catalog. Turning a plugin off turns off the ones that depend on it. Settings › Plugins shows them as Depends: ….

A plugin gives things to those that depend on it in provides: any object. They read it with api.plugin('its-id'), which is null while that plugin is off.

The 3D plugin (solid) provides two things, which MC Toolkit is built on:

A sign and a color

icon is the name of one of the program's signs; color is the color it is shown on, as #RRGGBB. Together they are the plugin's badge in the list of plugins and in the catalog. A plugin that sets neither has a plug, on a color made from its id.

const plugin: Plugin = {
  id: 'sunburst',
  name: 'Sunburst',
  version: '1.4.0',
  icon: 'star',
  color: '#F0834F',
};
export default plugin;
from rassam import Plugin

plugin = Plugin('sunburst', 'Sunburst', version='1.4.0', icon='star', color='#F0834F')

An icon of your own

icon may be a picture of the plugin's own instead of a sign's name. It fills the badge (a square with rounded corners), so draw it to the edges; 128 by 128 is plenty. It can be given three ways:

AsGood for
The text of an SVG, starting <svgA plugin in one file: the icon travels inside it.
A data:image/… addressA PNG, JPEG, WebP or GIF kept inside the file.
A web address, https://…A picture kept elsewhere. It needs the network to show.
const plugin: Plugin = {
  id: 'sunburst',
  name: 'Sunburst',
  version: '1.4.0',
  icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
    <rect width="24" height="24" fill="#F0834F"/>
    <circle cx="12" cy="12" r="5" fill="#FFF1C9"/>
  </svg>`,
};
export default plugin;
from rassam import Plugin

ICON = '''<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
  <rect width="24" height="24" fill="#F0834F"/>
  <circle cx="12" cy="12" r="5" fill="#FFF1C9"/>
</svg>'''

plugin = Plugin('sunburst', 'Sunburst', version='1.4.0', icon=ICON)

In a catalog, an entry's icon may also be a place beside the catalog (icons/sunburst.png), like its url. A picture that cannot be shown is replaced by the plug.

How updates are found

The program reads a catalog of released plugins. For each installed plugin, it looks for a release with the same id. When that release's version is later than the installed one, the plugin is marked in Settings › Plugins with the new version, what is new in it, and an Update button.

The catalog

A catalog is one JSON file: a list of releases under plugins (a plain list works too). The one that comes with the program is plugins/index.json, beside the program's own files.

{
  "name": "Rassam plugins",
  "plugins": [
    {
      "id": "sunburst",
      "name": "Sunburst",
      "version": "1.4.0",
      "author": "You",
      "about": "An element to insert: rays round a middle, as many, as long and as thick as you say.",
      "category": "Elements",
      "tags": ["insert", "shapes"],
      "language": "ts",
      "url": "sunburst.ts",
      "icon": "star",
      "color": "#F0834F",
      "released": "2026-10-05",
      "size": 1512,
      "changes": "Rays are filled wedges now, with a hole and a thickness to set.",
      "screenshots": ["shots/sunburst-1.svg", "shots/sunburst-2.svg"]
    }
  ]
}
KeyWhat it is
idrequiredThe plugin's id, exactly as its file says it. It is what ties a release to an installed plugin.
namerequiredIts name, as the catalog shows it.
urlrequiredWhere the plugin's file is. A place beside the catalog (sunburst.ts, files/sunburst.ts) or a whole https:// address.
versionThe version of the file at url. Raise it here and in the file together: it is this one that is compared.
languagets or py. Left out, it is taken from the end of url. (A plugin is not written in plain JavaScript: an entry that is one is left out.)
aboutWhat it does, in a sentence or two (up to 600 letters).
authorWho wrote it.
categoryThe kind it is listed under at the left of the catalog (Filters, Elements…). Any name makes a kind; one that has none is under Other.
tagsUp to eight words it is found by.
icon, colorIts badge: the name of a sign or a picture of its own (here it may be a place beside the catalog too), and #RRGGBB.
screenshotsUp to eight pictures of it at work, each a place like url. The first is shown across the top of its card; all of them are in its details, and open large when pressed.
changesWhat is new in this version. Shown with the update.
releasedThe day it was released, as 2026-10-05.
sizeThe size of the file, in bytes.
needsThe ids of the plugins it depends on. They are installed with it.
bundledtrue for a plugin whose code is kept inside the program itself (the MC Toolkit plugin is one). It has no url: nothing is fetched, but it is installed and removed like any other, and it is updated with the program. (An entry with the id of a plugin that comes with the program, such as the Compositor or the 3D plugin, is shown as coming with it: installing it turns it on.)

An entry without an id, a name or a file it can find is left out, and so is one whose file is neither on the web nor beside the catalog. A plugin's file may be no larger than 2 MB.

Screenshots

Any picture a browser shows will do: PNG, JPEG, WebP or SVG. They are shown at 16 to 9 and cropped to fit, so make them that shape; 1280 by 720 is a good size. Show what the plugin makes rather than its settings, and put the best one first.

Releasing a version

  1. Raise version in the plugin's file.
  2. Put the file where the catalog's url points.
  3. In the catalog, set the entry's version to the same number, and say what is new in changes.
  4. In the program, choose Check for updates: the installed plugin offers the new version.

A catalog of your own

The program reads one catalog. To have it read another (a team's, a community's), build the program with VITE_PLUGINS_URL set to the catalog's address:

VITE_PLUGINS_URL=https://example.com/plugins/index.json npm run build

The server must let the program fetch the catalog and the files (it answers with Access-Control-Allow-Origin). A plugin that is not in the catalog can still be installed from its file; it is listed under Custom plugins, and is not looked for in the catalog unless a release with its id appears there.

A catalog decides what code is offered to everyone who reads it, and a plugin can read and change projects. Serve it over https, and list only plugins you have read.