Suwatte

Source lists

The catalogue that the toolchain emits, where the metadata of a source comes from, and how to host it.

A person does not install a source file. That person adds a source list, then installs a source from it.

The npx suwatte build command makes the list for you. It reads the static info property of each delegate class.

What the build emits

dist/
├── sources/
│   ├── en.example.stt
│   └── ja.example.stt
├── sources.json
├── index.html
├── main.css
└── catalog.js

The .stt files are the bundles. The sources.json file is the list. The webpage gives a person a link to install each source when you host the output directory.

The list format

{
  "catalogVersion": 2,
  "generatedAt": "2026-08-27T12:00:00.000Z",
  "listName": "Example Source List",
  "sources": [
    {
      "id": "en.example",
      "name": "Example",
      "version": 1.4,
      "website": "https://example.org",
      "thumbnail": "example.png",
      "minSupportedAppVersion": "7.0.0",
      "languages": ["en"],
      "rating": 0,
      "path": "en.example",
      "variantId": "en.example",
      "sourceId": "example",
      "environment": "jsc"
    }
  ]
}

The toolchain writes catalogVersion, generatedAt and listName for the complete list. Set the display name with suwatte.listName in your project’s package.json; otherwise the package name is used.

The fields

Field Necessary Notes
id Yes Stable and unique. A change makes a different source.
name Yes The name in the app.
version Yes A number, not a string. The app compares it to find an update.
website Yes The site that the source reads.
thumbnail No A file name below the assets folder.
minSupportedAppVersion No The app compares it as a number, so 10.0 is more than 9.9.
languages Yes The languages that the source supports.
rating Yes A numeric ContentRating value.
path Yes The artifact name below the sources folder, without .stt.
variantId Yes The stable identifier for this variant.
sourceId Yes The source directory that produced the artifact.
environment Yes jsc or webkit.
config No Configuration metadata for the variant.

Where the assets go

The app reads a thumbnail from <list address>/assets/<thumbnail>. Use this layout:

/sources.json
/assets/example.png
/sources/en.example.stt

Two gates before an install

  1. version decides if an installed source is old. It is a number, so 1.10 is less than 1.9. Select a scheme that this does not break.
  2. minSupportedAppVersion decides if the app is new enough. The app shows a source that needs a newer app but does not install it.

Set minSupportedAppVersion when you start to use an interface that an older app does not have. Without it, an old app installs your source and then fails while a person uses it.

Host the list

A list is a static file. Any host that serves JSON over HTTPS works. GitHub Pages is a common choice.

Serve the list and its bundles from the same origin, so that the path value and the assets folder resolve correctly.

To test on your own network, use npx suwatte serve. See The command line.

Updates

Settings → Sources → Source Updates → Update Sources Automatically checks each installed source one time each day.

To release a repair, raise the version value and build again. Each person gets it without any action. This is the quickest way to correct a source for everybody.