Addons
An addon teaches EverythingBox about a new source of things to browse. It is a manifest and a script, and it runs sandboxed.
EverythingBox ships the engine, not the sources
The application provides the addon runtime, the catalog model, and a metadata addon that fills in artwork and descriptions. It ships no media, and it does not come configured to point anywhere in particular. What you connect it to is your decision and your responsibility.
Sandboxed
Each addon runs in an isolated JavaScript interpreter with a per-call execution timeout, so a runaway script cannot lock up the interface.
Never blocks the app
Calls run off the interface thread, each in a fresh context. No addon can freeze the app while it waits on a slow network.
Configurable
An addon declares its own settings schema and the app renders a form for it. Values persist per addon, and the script reads them back with getConfig.
What they produce
EverythingBox ships with a catalog addon covering films, shows, games and music. Add your own API keys in its configuration screen and a folder of filenames turns into this — posters, backdrops, ratings, genres and descriptions, with series expanding to their episodes.


Installing one
Addons are distributed as .addon files. Open the library, choose to install, and pick the file. Each source can be enabled or disabled individually, and the setting sticks.
Writing one
Two files. A manifest describing what you provide and what you need configured:
{
"id": "com.example.myaddon",
"name": "My Addon",
"version": "1.0.0",
"catalogs": [
{ "id": "popular", "type": "movie", "name": "Popular" }
],
"settings": [
{ "key": "apiKey", "type": "password", "label": "API key" }
]
}And a script that answers for it. The host gives you HTTP, storage, logging and your own configuration values:
// main.js
function getCatalog(catalogId, args) {
var res = httpGet("https://example.com/api/" + catalogId +
"?page=" + args.page + "&key=" + getConfig("apiKey"));
var data = JSON.parse(res);
return {
items: data.results.map(function (r) {
return { id: String(r.id), title: r.title, poster: r.image };
}),
hasMore: data.page < data.total_pages
};
}
// Optional: a series expands to its episodes, an album to its tracks.
function getDetail(id) {
var res = httpGet("https://example.com/api/item/" + id);
return JSON.parse(res);
}Catalogs support search and pagination as well as drill-down. The full contract is documented in theapp repository.