@multiplatform.one/cli
v7.4.1
Published
multiplatform.one cli — mpo init / create-multiplatform-app
Readme
@multiplatform.one/cli
The multiplatform.one command line: scaffold new multiplatform projects
(mpo init / create-multiplatform-app), manage the monorepo dev
environment, and drive Frappe + E2E workflows.
Install
pnpm add -g @multiplatform.one/cli
# or run the scaffolder without installing:
npx [email protected]/cli create-multiplatform-app my-appTwo binaries: mpo (full CLI) and create-multiplatform-app
(scaffolder only).
Scaffold a project (recommended)
mpo init my-app # universal: web (SSR) + iOS + Android via one
cd my-app
pnpm install
pnpm dev # web + native dev server
pnpm ios # build & run the iOS dev client (pnpm dev in another terminal)mpo init creates a consumer project — not a monorepo fork. It prompts for
anything omitted (name; platforms, defaulting to universal); pass --yes for
CI. @multiplatform.one/* dependencies come from npm at semver ranges, never
workspace:*.
Universal layout: apps/<name> (routes + providers + vite/expo config),
features/<name> (starter Home/About screens, forms demo, vitest),
packages/config, packages/i18n (en/es), packages/themes (Tamagui theme).
Want web-only? mpo init --web my-app scaffolds the Vite + React variant
(--app is a back-compat alias; create-multiplatform-app without flags also
produces it — pass --universal there for the full project).
Options: --universal, --web/--app, --skip-install, --skip-git,
--mpo-version <range> (defaults to ^<cli version>), -y/--yes.
Pieces
Composable fragments overlaid onto the base template. Pass any of them to skip
the interactive prompt; they are recorded in .mpo.json and reproduced by
mpo update, so pick them at init time.
| Flag | Adds | Needs |
| ------------ | ---------------------------------------------------------------- | --------------------- |
| --frappe | Frappe backend wiring — env keys, provider, dev bench compose | Docker |
| --keycloak | Keycloak auth — env keys, provider, compose + realm import | Docker |
| --gnome | GNOME desktop: real GTK4 widgets via react-gnome, no webview | gjs, gtk4, libadwaita |
| --vscode | VS Code extension — extension host + Tamagui webview | — |
| --webext | Browser extension — MV3 popup + background | — |
--gnome is the desktop piece. It renders your Tamagui components as native
GTK widgets laid out by Yoga — not the web build in a frame — so the app looks
and behaves like part of the desktop. Linux-first.
Update a project
mpo update upgrades a project to the current templates with a three-way
merge driven by .mpo.json (written at init time): base = the original
scaffold regenerated at the recorded CLI version, ours = your HEAD, theirs =
a fresh scaffold from the current CLI. .updateignore entries (exact files or directory prefixes — not globs) (and
pnpm-lock.yaml) stay pinned to your version; package.json dependency-range
drift auto-resolves to the newer minimum.
Idempotency contract: re-running mpo update immediately after a
successful update makes zero changes (clean git status). Run it, see no
changes, know you're current.
Adopt an existing project
A project that was never scaffolded — it hand-copied a delivery target
(webext, gnome, …) and uses @multiplatform.one/* from npm — has no
provenance. Bring it under mpo update management:
mpo adopt --webext --name my-app # requires a clean git tree; ≥ 1 pieceAdoption writes .mpo.json (template "none" + pieces) and seeds
.updateignore; it changes no project files. The FIRST mpo update
afterwards reconciles the piece files from an empty merge base, so diffs and
conflicts on hand-copied files are expected — resolve and commit. Later
updates are ordinary three-way merges (baselines come from
mpo init --pieces-only at the recorded version).
Bootstrap missing provenance
Scaffolded before .mpo.json existed (CLI ≤ 6.3.0)? Assert the version it
was scaffolded with instead of hand-writing the file:
mpo update --assume-version 6.3.0 [--template universal|app]Update a project
mpo update upgrades a project to the current templates with a three-way
merge driven by .mpo.json (written at init time): base = the original
scaffold regenerated at the recorded CLI version, ours = your HEAD, theirs =
a fresh scaffold from the current CLI. .updateignore entries (exact files or directory prefixes — not globs) (and
pnpm-lock.yaml) stay pinned to your version; package.json dependency-range
drift auto-resolves to the newer minimum.
Idempotency contract: re-running mpo update immediately after a
successful update makes zero changes (clean git status). Run it, see no
changes, know you're current.
Adopt an existing project
A project that was never scaffolded — it hand-copied a delivery target
(webext, tauri, …) and uses @multiplatform.one/* from npm — has no
provenance. Bring it under mpo update management:
mpo adopt --webext --name my-app # requires a clean git tree; ≥ 1 pieceAdoption writes .mpo.json (template "none" + pieces) and seeds
.updateignore; it changes no project files. The FIRST mpo update
afterwards reconciles the piece files from an empty merge base, so diffs and
conflicts on hand-copied files are expected — resolve and commit. Later
updates are ordinary three-way merges (baselines come from
mpo init --pieces-only at the recorded version).
Bootstrap missing provenance
Scaffolded before .mpo.json existed (CLI ≤ 6.3.0)? Assert the version it
was scaffolded with instead of hand-writing the file:
mpo update --assume-version 6.3.0 [--template universal|app]Other commands
| Command | Purpose |
| ---------------------------- | -------------------------------------------------------------------- |
| mpo init --monorepo [name] | DEPRECATED: clone/modify the full monorepo (framework dev forks) |
| mpo adopt | Write provenance into an existing, never-scaffolded project |
| mpo update | Three-way template update via .mpo.json (legacy merge for forks) |
| mpo wait | Wait for a service (frappe, postgres, mariadb, keycloak) to be ready |
| mpo frappe bootstrap | Bootstrap the Frappe development environment |
| mpo frappe dev | Start the Frappe development server |
| mpo frappe bench -- <args> | Run a bench command |
| mpo frappe clean | Clean Frappe bench artifacts |
| mpo build | Run the build command |
| mpo test | Run tests (E2E flags: --up-only, --down, --filter, …) |
Development
Templates live in templates/universal/ and templates/app/. Generator unit
specs: pnpm --filter @multiplatform.one/cli test
(src/commands/initApp.spec.ts — tree + package.json shape for both templates).
What it must not do
- The project templates never ship
workspace:*dependencies on@multiplatform.one/*or copies of the monorepo'spublic/packages — consumers upgrade via npm (pnpm update "@multiplatform.one/*")
License
Apache-2.0
