mix mob.deploy (mob_dev v0.3.37)

Copy Markdown View Source

Compiles the project then pushes BEAM files to all connected Android devices and iOS simulators.

Modes

Fast deploy (default) — push BEAMs + restart. Use this for day-to-day Elixir code changes. Requires the native app already installed on device.

mix mob.deploy

Full deploy — build native binary + install APK/app + push BEAMs. Use this the first time, or after changes to native C/Java/Swift code.

mix mob.deploy --native

Options

  • --native — build native binaries before pushing BEAMs
  • --no-restart — push BEAMs but don't restart the app
  • --device <id> — target a specific device; use mix mob.devices to find IDs
  • --schedulers <N> — set BEAM scheduler count (saved to mob.exs)
  • --beam-flags "<flags>" — arbitrary BEAM flags string (saved to mob.exs)
  • --slim — strip OTP source/debug for size measurement on
                          a real device. OFF by default for dev iteration
                          (the strip pass adds ~5-10s per build); use this
                          to verify a slim build runs before
                          `mix mob.republish` round-trips through TestFlight.

BEAM scheduler tuning

The default native build uses 1:1 (single scheduler) for battery efficiency. Override for the current deploy and all future deploys until changed:

# Pin to 2 schedulers
mix mob.deploy --schedulers 2

# Let BEAM auto-detect — one scheduler per logical core
mix mob.deploy --schedulers 0

# Arbitrary flags (replaces --schedulers)
mix mob.deploy --beam-flags "-S 4:4 -A 4"

The chosen value is written to mob.exs under beam_flags: and reused on subsequent mix mob.deploy runs that don't pass either flag. The flags are written alongside the BEAMs as a mob_beam_flags file that the native launcher reads at startup — no APK/app rebuild required.

Under the hood

A fast deploy is equivalent to:

mix deps.get                                     # only with --native
mix compile

# Android
adb push _build/prod/lib/*/ebin/*.beam /data/data/<pkg>/files/lib/*/ebin/
adb shell am force-stop <package>               # restart

# iOS simulator
xcrun simctl spawn <udid> cp <beam_files> <app_bundle>/

When Erlang distribution is already reachable (app running, node connected), mix mob.deploy skips adb push and hot-pushes via RPC instead — equivalent to calling nl(Module) in IEx for every changed module:

:rpc.call(node, :code, :load_binary, [Module, path, beam_binary])

With --native, it also runs the platform build before pushing BEAMs:

# Android
./gradlew assembleDebug
adb install -r app/build/outputs/apk/debug/app-debug.apk

# iOS simulator
xcodebuild -scheme <app> -destination 'platform=iOS Simulator,...' build
xcrun simctl install booted <app>.app