Mob is fully featured — but since 0.7.0 the capabilities live in focused
packages rather than one monolithic core. Core ships the kernel every app
needs (screens, navigation, rendering, state, storage, permissions,
distribution, the test harness, and the neutral light/dark/adaptive
themes); everything else is one dep + one config line away.
Activating any capability plugin is the same two steps:
Every phone sensor: MobSensors.list/0, one-shot read/2, streaming start/2 / stop/1, step history steps/2. Includes barometer, proximity, light, humidity, temperature, step counter and vendor sensors
Android lists every SensorManager sensor. iOS covers CoreMotion, CMAltimeter, CMPedometer and proximity, with no ambient light. Step sensors need :activity_recognition. For accelerometer/gyro/heading in core, see Mob.Motion
Speech-to-text: MobSpeech.listen/2, stop/1, cancel/1, with {:speech, :state | :partial | :final | :error, …} events and a pluggable engine
The default engine is the platform recognizer (Android SpeechRecognizer, iOS SFSpeechRecognizer); pair with mob_whisper for offline recognition. Text-to-speech stays in core (Mob.Speech).
Offline speech-to-text on the device: whisper.cpp as a mob_speech engine (engine: MobWhisper)
No Google/Apple speech service needed. The model (base_en default, tiny_en option, ~60 MB) downloads once with a SHA-256 check; MobWhisper.prefetch/0 fetches it ahead of time. Verified on a Moto G 2021; iOS builds but hasn't run on a device.
Global device-audio capture: meters audio that other apps or native players produce (Android MediaProjection / AudioPlaybackCapture)
A test-environment probe for audio the in-app Mob.Audio probes can't reach. Android only; iOS has no API for this and returns {:error, :unsupported_on_platform}. 0.1.2 on Hex.
System SMS composer pre-filled with recipient + body
MobSms.compose/2 on both platforms. iOS observes send / cancel via the MessageUI delegate; Android hands off to the user's SMS app (outcome unobservable — see the plugin's per-platform-delivery docs). No permissions on either platform.
For episodic work fired by the OS or a silent push (server-side push via mob_push using MobWake.wake_payload/2). Foreground + backgrounded verified end-to-end on Moto G Power 5G 2024 + iPhone SE 3rd-gen (MOB-268 / MOB-271); force-quit drop is intentional platform behaviour on both OSes.
Keep-alive execution while backgrounded — iOS silent-audio session, Android foreground service
For continuous work (music, upload, walk tracker) that the user has explicitly kicked off. Not the same as mob_wake — mob_background keeps a process alive while backgrounded; mob_wake wakes a specific handler on an OS event. They stack. See Background execution.
On-device Nx backend backed by Eigen — the header-only C++ linear-algebra library, NEON-vectorised on ARM. Always-available CPU baseline for on-device numerics — needs no GPU, runs anywhere mob runs.
GPU-accelerated backends (mob_nx_vulkan, mob_nx_mlx, mob_nx_tflite) planned to layer on top; NxEigen is the fallback that always works. Spike; API surface still narrow.
On-device OCR: recognize text in a still image file
iOS Vision (VNRecognizeTextRequest), Android ML Kit text recognition (bundled Latin model). No network and no runtime permission. Pairs with mob_camera / mob_photos for the image. Face and pose detection are planned. 0.1.2 on Hex.
TensorFlow Lite from the BEAM with vendor accelerators: Apple Neural Engine on iOS, MediaTek/Qualcomm GPU and NPU HALs on Android
Install with mix mob.enable tflite (mob_dev), not config :mob, :plugins: it adds the dep and registers the static NIF. Runs pre-compiled .tflite models; it is not an Nx backend. 0.0.4 on Hex.
3D rigid-body physics: Rapier as a Rustler NIF, with a named-world registry and face-up decode rules for dice
Not activated via config :mob, :plugins: register the NIF in mob.exs with config :mob_dev, static_nifs: [%{module: :lab_physics, archs: [:all]}] and set config :mob_rapier, :otp_app, :my_app (see its README). Physics only; render with mob_scene3d or your own view. 0.1.0 on Hex.
73 Mishka Chelekom composites for Mob apps — dialogs, tabs, accordions, hue / alpha / range / angle sliders, semi-circle progress, JSON input, and more
Shipped as a proper Hex plugin (replaces the pre-mob_new 0.6 vendoring pattern). Reads Mob's theme tokens (see Theming), so switching Mob.Theme.set/1 re-skins every composite at once, identically on both platforms. mix mob_mishka.gen <name> ejects a specific composite into your lib/<app>/components/ for editing with config :mob_mishka, :override_namespace, MyApp.Components. mix mob_mishka.migrate converts pre-plugin vendored apps in one pass. Design system upstream: mishka-group/mishka_chelekom (Shahryar Tavakkoli / @shahryarjb).
Reference server for mob_deliver: compiles a Phoenix project's mobile/ tree into content-addressed BEAMs, signs the manifest, and serves it from a Plug
Choosing plugins for an app
The catalog is deliberately un-monolithic — you pay for what you activate.
Some pairing hints:
Verification / OTP flow.mob_sms + the built-in text-field
text_content_type: :one_time_code prop (mob 0.9.1+) covers iOS
QuickType autofill; mob_sms's MobSms.OneTimeCode.arm/2 covers
Android via Google Play Services' SMS Retriever. Same shape on both
platforms, no READ_SMS permission on Android.
Camera-centric app.mob_camera for capture + preview,
mob_scanner if you want QR/barcode as its own screen (activates
:camera under the hood), mob_photos for picking existing images
from the library. mob_video for on-device editing.
Sensor / peripheral app.mob_bluetooth for BLE + BR/EDR,
mob_midi for musical instruments, mob_location for GPS,
mob_sensors for barometer, proximity, light, steps and every other
phone sensor, mob_touch if you need the raw touch stream.
Background sync.mob_notify for local reminders, mob_wake
for OS-triggered handlers (scheduler firings + silent-push receive),
mob_background for continuous keep-alive while the app is
backgrounded. Three distinct concerns — see each plugin's moduledoc
for the "which one do I want" table.
Design system.mob_mishka gives you 73 composites; mob_themes
gives you five preset visual looks that all composites read from.
Push notifications end-to-end.mob_notify on the client
(register for pushes, receive them) + mob_push on your server
(send APNs / FCM).
Building your own
Pure-Elixir UI kits: function composites work with a plain Hex dep, and
tag-name composites via Mob.Composite — see the
Components guide.
Anything deeper: mix mob.new_plugin --tier 0|1|2|3|4 scaffolds a plugin
with tests; the Plugins guide and the
manifest reference cover the rest.
If your plugin will fill an obvious gap in the first-party catalog above,
reach out — happy to review, credit, and potentially adopt it into
first-party status once it stabilises.