Skip to main content

Building an app

This chapter follows the current repository workflow: author an app module and frontend, build a target-neutral .neutron archive, then install it through the reviewed browser flow or a complete local provisioner config.

PageCovers
Getting startedPrerequisites and the exact copy, package, test, local-run, install, and update commands
Project layoutEvery file in an app project and what owns it
The Motoko backendModules, Init, annotations, memory, and capabilities
The frontendTiles, the SDK, calling your own backend, backgrounds, and trays
Design systemUsing the shared dark UI and its rules
TestingUnit tests, security fixtures, migration tests, and browser coverage

Three boundaries to learn firstโ€‹

The backend source is a module, not a canister actor. It exports public class Init(env : AppBackendEnvironment). The compiler consumes annotated class methods to generate the appropriate wrappers and injects resources such as caller only when the annotation requests them.

Apps share one assembled canister actor. An app is not deployed as a separate canister, but that does not mean it receives unrestricted platform access. The compiler derives its backend environment from the manifest, scopes app-owned resources, and rejects prohibited Motoko APIs. Isolation is enforced by compilation and kernel runtime contracts rather than a canister boundary.

Persistent Motoko state uses managed memory. Declare each root and its schema version in the manifest. A released schema is locked; type changes add a new schema and forward migration edges instead of editing history. Other durable platform services, such as Stable Store or persistent browser storage, are separate manifest-declared capabilities with their own scoped contracts.