Mentra Miniapp SDK betaThe SDK is in beta, so its APIs may change before general availability.There is currently no way to distribute a miniapp built with the Miniapp SDK. In a future release, developers will upload miniapps through the Mentra Developer Console, and users will download them from the Mentra Miniapp Store. Neither service supports Miniapp SDK distribution in MentraOS 3.0.Only use the Miniapp SDK if you are comfortable with these limitations.Developing on Mentra Live? We recommend using the Mentra Bluetooth SDK.The developer tools are available in the Mentra App under Settings → Miniapp Developer Settings.Share feedback with an in-app bug report, on Discord, or by email at help@mentra.glass.
@mentra/miniapp-cli provides the mentra-miniapp command. It’s installed as a dev dependency in every scaffolded project, so your package.json scripts call it directly ("dev": "mentra-miniapp dev").
Run with no arguments to print the usage table.
The CLI is Bun-only: it ships as TypeScript and runs under Bun. Use bun (or bunx), not npx/Node.

dev

Validates miniapp.json, builds both layers, serves them over your LAN, and prints a QR (and a miniapp://dev?... URL). It also runs a dev sidecar WebSocket on the next port up for live reload and console-log forwarding back to your terminal (non-fatal if it can’t start). It watches for Wi-Fi/LAN-IP changes every 10 seconds and reprints the QR. The starting port comes from "port" in miniapp.json (default 3000); if it or its sidecar neighbor is busy, the CLI scans upward for a free adjacent pair. On the phone: In the Mentra App, open Settings → Miniapp Developer Settings → Scan Miniapp QR Code. Phone and laptop must share Wi-Fi. Ctrl+C stops everything.
dev is live and temporary. Keep the CLI and computer running: the Mentra App loads the runtime bundle from that LAN server. Dev miniapps are keyed by their manifest package name, so you can scan and test several side by side; rescanning the same package updates only that entry. The Mentra App caches each entry’s name and icon. Use bun run release for an installed miniapp that works without the computer.

release

The all-in-one path for putting a build on real devices: validate → build → pack → serve behind a QR so you can install on as many phones as you want. It reuses a cached build/<pkg>-<version>.zip when every source file is older than the zip, otherwise rebuilds (auto-detecting your package manager from the lockfile). It serves the bundle, manifest, and icon over HTTP on 0.0.0.0 and prints a miniapp://release?... QR, then stays up so multiple devices can install. Each install logs a line. Installed miniapps run offline and persist across restarts; no laptop needed after install. The bundle is unsigned unless you pass --sign or --signing-key; see Signing. A cached ZIP is reused only when it matches the signing you asked for.

pack

Produces the release artifact only (release calls this internally). It builds with NODE_ENV=production, verifies dist/, validates the manifest, copies miniapp.json + icon.png into dist/, and zips to build/<pkg>-<version>.zip, replacing an older ZIP only after the new one is complete. It prints the bundle’s SHA-256 and its publisher key, or unsigned. In a future release, this ZIP will be uploaded through the Mentra Developer Console for distribution in the Mentra Miniapp Store. That distribution workflow is not available in MentraOS 3.0.
pack requires the zip binary on PATH (preinstalled on macOS and most Linux; on Windows use WSL). build/ self-ignores from git.

Signing

Bundles are unsigned by default. --sign signs with the package’s stored publisher key (see keys); --signing-key <path> signs with a key file without storing it, for CI. CI can also set MENTRA_MINIAPP_SIGNING_KEY_FILE or MENTRA_MINIAPP_SIGNING_KEY_JSON together with --sign. A signed ZIP carries META-INF/MENTRA.SIG: the package’s Ed25519 public key and a signature over its package name, version, manifest and every file.
Signing is permanent for a package. The first signed bundle a phone installs records the publisher key, and from then on that phone accepts only bundles signed with the same key. An unsigned bundle or a different key is refused until the user uninstalls the miniapp. There is no key rotation, so back up the key (keys export) before you ship a signed bundle. Signing needs a lowercase reverse-DNS package name (letters, digits and underscores).

keys

Manages one publisher signing key per package. Keys are stored in the OS keychain, or in a mode-0600 file under ~/.mentra/cli-v2/signing-keys/ when the keychain refuses the write. If the keychain can’t be read, key commands stop without creating or changing a key; on machines without a keychain, such as CI, sign with --signing-key. show prints the key’s sha256: fingerprint. export writes the private key to a new file; keep it secret and in a secure backup.

manifest

An interactive wizard for miniapp.json: edit permissions and hardware requirements, show the current manifest, or finish. It saves after each confirmed change, so Ctrl+C never loses a saved edit.

permission and hardware

Object-verb edits that share the wizard’s validation:
Permission TYPE: MICROPHONE, CAMERA, CALENDAR, LOCATION, BACKGROUND_LOCATION, READ_NOTIFICATIONS, POST_NOTIFICATIONS. Hardware TYPE: CAMERA, DISPLAY, MICROPHONE, SPEAKER, IMU, BUTTON, LIGHT, WIFI; LEVEL: REQUIRED, OPTIONAL. See the manifest for what each means.

schema

Prints the canonical miniapp.json JSON Schema to stdout: useful for CI validation or IDE config. The same schema ships at node_modules/@mentra/miniapp-cli/schema/miniapp.schema.json, which the $schema line in a scaffolded miniapp.json references for editor autocomplete.