# What is an app, and how does it get onto a display?

An app is a domain-specific extension of the platform: a manifest, at most one widget, and, if needed, a backend. This page follows its lifecycle from the manifest to the widget in the scene — and says which parts are open to whom today.

> **Type:** concept
> **For:** Developers who want to understand how an app is built before they read the manifest, widget, or backend.
> **Prerequisite:** none. Knowledge of TypeScript helps with reading the examples.

An app does not start a process of its own. It is a package that the platform loads, and it shows up in four parts. The first is the **manifest** with identity, widgets, permissions, data access, and signing policy. The second is an optional **backend** with resolver, fetcher, and jobs. The third is the **runtime** bundle that the player loads, and the fourth is the **authoring** bundle with the configuration form for the scene editor. The manifest is the one binding description: what is not stated there does not exist for the catalog, portal, and device. Each app has at most one widget. The app is the unit that an organization installs, evaluates, and removes, and a widget handles several presentations through its preview variants and a configuration field.

How much machinery an app carries falls into three levels. Some of the bundled apps render solely from their configuration and have no backend (`clock`, `webpage`, `notice-board`, `countdown`, `countup`, `world-clock`, `word-clock`, `ticker`, `qr-code`, `youtube`, `stream`, `embed`). `weather`, `rss`, `tagesschau`, and `calendar` pull from external sources with a fetcher, and the brand apps `bbc`, `bild`, `deutschlandfunk`, `ndr`, and `spiegel` inherit the backend and widget from `tagesschau`. `pharmacies-on-duty`, with a fetcher and a recurring job, and `menu-board`, without any outbound retrieval, keep their own resources in an app database of their own. `opening-hours` gets by with a backend that only reads the location, without a fetcher, resources, or a database. In addition there are the gate apps without a visual surface, `onedrive` and `video-wall`: they bring no widget but unlock a feature of the portal. The complete list is the `apps/` folder.

An app gets onto the display in four stages. Platform operations creates a **release** from the manifest and bundle. It freezes the version, manifest, and bundle reference and starts in the `canary` channel, from which it is promoted step by step through `beta` to `stable`. An organization **installs** the app from the catalog. The installation has three states: active, **Update waiting** (when a new version in `stable` demands more permissions, data access, or changed terms, or when the installed one expires), and uninstalled. The **device** reads from the scene snapshot, for each app, the one version that the display plays: the installed one, because scenes of the same major version follow it. If a scene of the display deliberately holds an older major version, the display plays that version for all of its scenes, and the scene carries a notice until someone raises it. The device fetches the missing bundle through `GET /v1/apps/{appId}/{version}/bundle.zip` and checks the `sha256` value and the Ed25519 signature before it unpacks. The **renderer** first checks whether the version fits it: the manifest states in `apiCompatibility.rendererHost` the host contract that the bundle needs, and the renderer loads only what its own contract version covers. Then it loads the runtime bundle and has it register its widget. A bundle that does not fit is not loaded in the first place. One that brings no widget, registers a widget that is not its own, or fails while loading is reported (`widget.bundle.no-exports`, `…foreign-widget`, `…load-failed`) instead of tearing down the scene. The **scene editor** loads the runtime and authoring bundles the same way from the installed version and shows their widgets and forms.

![App lifecycle: manifest and release with platform operations, channels up to stable, installation in the organization, bundle retrieval with verification, and widget in the renderer on the device](/apps-sdk/bilder/26165431-app-lifecycle.svg)

## What follows

- **Platform operations creates releases.** The catalog has no submission and no review queue. Creating, promoting, demoting, and retiring are operator work.
- **Apps are built in the platform’s source tree today.** The `@szenera/apps-sdk` SDK is a package of this source tree and is not published to npm. It does not travel with the services’ release train but has its own cadence.
- **New versions stay compatible.** Fields of a widget configuration are only added with a default and never disappear, because a version must read the configurations of its predecessors. An app’s backend runs in exactly one version and serves every version that a display still plays, so its routes, outputs, and responses change only additively, and every route keeps accepting what an earlier version sends. A test in every app holds both against a fixed baseline.
- **There is no submission path for third-party apps.** The following pages describe the contract that the bundled apps are written against, not a procedure that you could go through today.
- **The user’s view is in the handbook.** Installing, permissions, and terms from the organization’s point of view: [Apps in the handbook](https://szenera.com/docs/apps).

## Related

- [The manifest](/apps-sdk/manifest) — every field with whether it is required, its format, and its effect.
- [Signing and the path into the catalog](/apps-sdk/signing-and-catalog) — bundle, signature, channels.
- [Apps in the handbook](https://szenera.com/docs/apps) — the organization’s view.
