I’ve posted a couple times about this topic before:
I’m hoping the description below is close to the final iteration of what the Elixir community would like in a mobile app framework. Working title, mob.
BEAM-on-device mobile framework, looking for feedback
I am working on a mobile framework for Elixir that takes a different approach than what’s out there although it combines a bit of every approach so far. Looking for early feedback before going further.
The idea in one sentence:
Write mobile apps in Elixir using a LiveView-style lifecycle: mount, render, handle_event, where the BEAM runs directly on the device and drives native UI through NIFs. No server, no JavaScript, no WebView.
How it actually works:
The app shell (Android APK / iOS IPA) is a thin native wrapper that boots the BEAM on startup. From that point, Elixir owns the app. render/1 returns a component tree; the renderer walks it and makes NIF calls that create and mutate real native views — Android Views on Android, UIKit on iOS. State changes trigger a diff and only the changed views are updated. The native shell is just a display surface; all logic lives in Elixir.
defmodule MyApp.CounterScreen do
use Mob.Screen
def mount(_params, _session, socket) do
{:ok, assign(socket, :count, 0)}
end
def render(assigns) do
%{type: :column, props: %{padding: 16}, children: [
%{type: :text, props: %{text: "Count: #{assigns.count}"}},
%{type: :button, props: %{text: "+", on_tap: self()}}
]}
end
def handle_event("tap", _, socket) do
{:noreply, assign(socket, :count, socket.assigns.count + 1)}
end
end
If you already know LiveView, that lifecycle is immediately familiar. The intent is that transitioning to mobile should feel like learning a new set of components, not a new paradigm. That being said, delivering to the web is a dream come true in terms of distribution. We can’t get away from having to submit via app stores, etc. There very well could be some platform related glue code using gradle or plist files that you may still have to alter yourself. I’m not deep enough into it to know at this stage.
How it relates to existing work:
- LiveView Native — closest in spirit, but LVN requires a Phoenix server. Mob runs fully on-device; no server needed, works offline, no latency on interactions. When
people first heard “LiveView Native” a lot of them expected something like this — BEAM on the phone, LiveView-style code, native UI. LVN is excellent but it’s a
different tradeoff. - Elixir Desktop — proved BEAM-on-device is viable. Mob builds on that insight but targets mobile-native UI patterns (component trees, event model) rather than desktop
wxWidgets. - React Native — the component/props/event model is familiar territory for people coming from that world. mount ≈ component lifecycle, handle_event ≈ event handlers,
assigns ≈ state. The diff-and-patch render loop is the same idea.
Dev experience goals:
Dev mode connects the device to your machine over Erlang distribution (WiFi, mDNS), no USB required, works on Android and iOS identically). The device boots a minimal shell and dials home.
mix mob.dev
on the dev machine starts a file watcher; save a file and the new module is pushed to the device, same loop / experience as
mix phx.server
Full IEx shell into the running on-device BEAM: inspect GenServer state, trace function calls.
OTA updates are supported. Beam bytecode runs in the embedded BEAM VM; same interpreted-code exception that covers React Native/CodePush and LiveView Native.
Code-signed delivery.
Current status:
HelloScreen confirmed working on Android emulator, real Android phone (non-rooted), and iOS simulator.
What I’m looking for:
- Does the LiveView-on-device model resonate? Is this what you were hoping LVN would be?
- Component vocabulary: what would you reach for first beyond the basics?
- Any prior art I’m missing?
- Would you use this?
Non goals for the project
- All things to all people
- Not targeting anything outside of iOS, Android, although I think this approach is fairly easy to replicate if you want to build a desktop app for Windows, etc.
I have a larger planning document I coauthored with Claude but I wanted to avoid a wall of LLM text. I can post that as well if people are interested for a fuller vision of the project.
Working on Android / iOS and I’ve also run this on my own Android device.
One of the things I thought was a blocker but turned out to be fine was the BEAM boot time. It takes about half a second depending on hardware.























