The manifest
Every app describes itself in a solel-app.json. Solel reads it when the app is installed, checks it, and reads it again each time the app is updated.
An example
{
"schema": 1,
"id": "com.example.notes",
"name": "Notes",
"version": "1.2.0",
"description": "Quick notes that sync to every device.",
"publisher": "Example Ltd",
"icon": "data:image/svg+xml;base64,…",
"grants": ["files.read", "notify"],
"layouts": ["desktop", "phone"],
"frontend": { "url": "/" },
"backend": {
"image": "ghcr.io/example/notes@sha256:…",
"port": 8080,
"health": "/healthz"
},
"subdomain": "notes"
}
Fields
| Field | Required | What it is |
|---|---|---|
schema |
yes | Always 1 |
id |
yes | Reverse-DNS in lower case, like com.example.notes, up to 100 characters. It stays the same across versions. Ids starting io.solel. are Solel's own and can't be installed |
name |
yes | 1 to 40 characters |
version |
yes | SemVer, like 1.2.0, or a pre-release like 1.3.0-beta.1 |
description |
no | Up to 500 characters |
publisher |
no | Up to 80 characters |
icon |
no | A base64 data: URL of a PNG or SVG, or an https URL. See below |
grants |
yes | What the app may use for the person using it. It can be empty. See Grants |
layouts |
yes | desktop, phone or both |
frontend.url |
yes | An https address, or a path your back end serves, like / |
backend |
no | The container: an image pinned by digest, the port it listens on, and a health path that answers 200. See Back ends and workers |
subdomain |
no | Where the app is published, like notes. Needs a back end. See Addresses |
public |
no | Up to 10 paths at the app's address anyone may visit without signing in, like ["/s/"]. Each starts and ends with /. Needs a subdomain |
imports |
no | What the back end takes from Google Takeout: photos, mail, calendar, contacts, files. See Importing |
settings |
no | Up to 12 pages the app adds to Settings. See Pages in Settings |
The icon
Put the icon inside the manifest as a data: URL. The desktop never loads pictures from other sites, so an app with an https icon shows a plain tile in the dock and in Settings instead. The desktop shows your icon in the same rounded square as Solel's own; see Icons and tokens.
What Solel checks
- Unknown fields are refused, so a typo doesn't go unnoticed.
- Size. The whole file, icon included, is at most 256 KiB.
- Each once. A grant, an import or a public path can only be listed once.
- The image is pinned, as
registry/name@sha256:and the 64-character digest. A tag alone is refused. - A path needs a back end. A
frontend.urlthat's a path, asubdomainandimportsall need abackend.
When a manifest is refused, the message says which field and why, such as version "1.2" must be SemVer, like 1.2.0.
New versions
An update never goes back to an older version, and a pre-release counts as older than its release, so 1.3.0 can't be followed by 1.3.0-beta.2. Keep the same id for every version: a different one is a different app. See Try it on your own server for installing a new version while you work.