Docs

Definition

The definition object, how the hub identifies and versions an app, and the parent/child metadata.

const definition = {
  name: 'Porch Light',          // required — shown in the install picker
  namespace: 'com.example',     // required — a string you control; with name, it is the app's identity
  description: 'Light the porch at dusk.',
  author: 'Jane Developer',
  category: 'lighting',         // free text used for grouping: lighting, climate, security, automation, …
  iconUrl: '',                  // optional 1× icon
  iconX2Url: '',                // optional 2× icon
};

The full field list is on the SmartAppDefinition reference.

Identity

The hub identifies a definition by namespace + name. Registering code with the same pair again updates that definition instead of creating a second one, and every installed instance follows the update on its next run. Rename either field and you have a new, unrelated app.

Pick a namespace like a reverse domain (com.example) or an organisation handle. novon.system is reserved for the built-in apps.

Versioning

Do not put a version in the definition. The hub assigns an integer version to each definition and increments it whenever the stored source changes. (Some older examples show a semver string; it is ignored.)

Parent and child apps

A definition can declare that it hosts children, or that it is a child of another definition:

MetadataMeaning
childApps: [{ namespace, name }]this app is a container; the listed definitions can be installed under it
parent: { namespace, name }this app can only be installed under an instance of that parent
singleInstance: trueat most one instance per location
singletonPerParent: trueat most one instance per parent instance
deprecated: truehidden from the install picker; existing instances keep running

These live in the definition's metadata when the app is registered (built-ins declare them in a JSDoc manifest at the top of the file). How parents and children cooperate at run time is covered in Parent and child apps.

Writing style

The examples on this site declare definition and preferences as top-level consts and handlers as top-level functions; the hub reads them by name from the global scope. In TypeScript the built-ins use an explicit $g.definition = … assignment instead — see TypeScript authoring. Both work.

On this page