GenericJam

GenericJam

Mob - Native BEAM / Elixir on Native Mobile

Edit: 2026 May 15 - This post is archived.

Mob is alive!!

Main docs: mob v0.7.11 — Documentation

A bit of explanation for the slightly convoluted repo structure. There needs to be three repos:
mob lives in the app you create.
mob_dev is a dev dependency so it doesn’t make it into your production app. It creates a dev server which allows you to connect to the app while it’s running. Also it’s full of mix tasks and such to help you manage your devices, deploying code, etc.
mob_new is the installer which you install with mix archive.install hex mob_new

After that you just run these commands to create an app, install the dependencies and deploy to all the ios and android devices on your system:

mix mob.new my_app 
cd my_app
mix mob.install
mix mob.install --ios --android

The ethos of mob is combining the best of Elixir and the BEAM with the best of mobile. I think they both have good and interesting things to contribute. I want to make things useful and accessible while also being powerful. It is a developer first ecosystem with good ergonomics just like the rest of Elixir.

We already have the first app in the App Store: ‎AirCartMax App - App Store
We will soon (already have?) the first app in the Play Store: https://play.google.com/store/apps/details?id=com.beyondagronomy.aircartmax

So all of the questions regarding the viability of the project have been answered.
There were also some questions around battery usage. There are some battery tests in mob_dev you can run but this has been a non issue for all users as far as I can tell.


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.


First 10 of 106 Posts Switch mode

cmo

cmo

yes

yes

manhvu

manhvu

I like this idea.

I think we can join clusters between dev environments (dev machine ErlVM & mobile ErlVM), making it easier to debug, hot reload, and update state remotely.

Another interesting idea is integrating Nx for edge AI—if possible, this could save a ton of time when developing client apps with AI assistants.

For this I think adapt Impeller engine from flutter or other render engine.

Do you have a repo? I’d love to take a look.

derek-zhou

derek-zhou

I doubt you need to compute the diff. Just re-render the whole thing; you are not limited by the bandwidth or need to preserve the client state, like the Liveview does.

GenericJam

GenericJam

I also grabbed the hex name so it doesn’t get scooped in the meantime. Not super useful yet unless you just want hello world. Probably missing some instructions too.

manhvu

manhvu

I have took a look.

Currently, you wrapper to native components.

I will try to adapt Impeller engine in the near future. I think Flutter (using Impeller engine) has widget tree look like HTML then we can get some benefit from that.

GenericJam

GenericJam

I briefly considered Flutter.

I built a proof of concept using NativeScript with a remote server which does much of what LVN does.

You could do LiveView > LiveViewSvelte > Svelte > SvelteNative > NativeScript already if you were willing to build that chain. The proof of concept I built just cuts out everything having to do with Svelte. Then I realized you could just cut more out and do it direct. NativeScript utilizes the same direct access to the platform code.

So by putting the BEAM on the device and accessing the app via a NIF you cut out all the middlemen. You get the native behaviour and performance and you also get the BEAM which is kind of the whole point and writing in Elixir is the icing on the cake.

I worked for years in React Native and there are a lot of problems. One of them is you’re always one step removed. Whenever Android or iOS make big changes they facilitate them ahead of time in their IDEs but they don’t actually tell people necessarily. So the platforms like React Native will always be a half step behind because they have to react the day the new feature comes out. I want something where we can always have the option of just writing native code. When LVN was first announced I was very enthusiastic about the approach because you get a native app which is the industry gold standard.

Grouvie

Grouvie

Really interesting work. One thing I’m still trying to understand: Why do you dislike the idea of using LiveView as the runtime/rendering transport on mobile?

I’m working on something in a similar direction. It also embeds the BEAM on-device and uses a native bridge, but the rendering model is different: it boots Phoenix/LiveView locally and loads the loopback endpoint inside a WebView/WKWebView, then bridges native capabilities like notifications / clipboard / tray through the host layer.

So at a low level there seems to be a lot of overlap:

  • embedded BEAM
  • native bootstrap / bridge
  • local runtime
  • Elixir-first app logic

I think native components can be approached in a few ways. Wrapping Compose/Jetpack-style trees over JSON, going fully direct through a NIF/JNI view bridge on Android. Or through existing solutions like water-rs, NativeScript…

derek-zhou

derek-zhou

Your approach is also very cool. What @GenericJam is aiming is the full mobile app experience and the resulting apps are most likely delivered via app store. With your approach, you can probably get away with one standard graphic shell and let users bring their own elixir code (like from hex.pm) and assemble the app on device, bypassing the app store. I think both approaches have their own niche; can’t wait to see you guys to collaborate.

Grouvie

Grouvie

Thanks. I think there may be a slight misunderstanding though.

What I’m doing is also intended to run fully on-device and can absolutely be packaged and distributed as a normal App Store / Play Store app. The embedded BEAM, Phoenix, and LiveView runtime are bundled with the app itself.

So the difference I see is not really “app store app” vs “bypass app store”, but more the rendering boundary:

  • GenericJam seems to be pushing toward Elixir driving native views directly

  • my approach keeps LiveView as the UI layer locally on-device, with the host bridge handling native capabilities

So it’s still a packaged app, just with a different runtime/UI architecture.

In principle a generic shell is possible, but that’s not really the main thing I’m aiming for.

Where Next?

Trending in Announcing Top

bluzky
You may know https://ui.shadcn.com/, a UI component library for React. I really love it’s design style and components. I’ve built some co...
387 14960 120
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
shahryarjb
The Chelekom project is a library of Phoenix and LiveView components generated via Mix tasks to fit developer needs seamlessly. One of i...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New
ausimian
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New
quatermain
Hello, I’m sharing my plugin here in forum after some time so it has time to mature and proof yourself. I use Claude Code daily on a pr...
New

Other Trending Topics Top

type1fool
I just stumbled on a newly redesigned elixir-lang.org. :tada: It looks like @Software_Mansion did the work, and I think it is generally a...
New
akoutmos
@hugobarauna and I (Alex Koutmos) have been hard at work on writing a book on Nerves that takes you from simply blinking LEDs to building...
New
juhalehtonen
There has been a thread to discuss the Stack Overflow Developer Survey on this forum every year since 2018, so here’s yet another one for...
New
bjorng
We want to introduce a new native datatype to Erlang: native records. Although replacing all tuple records with native records is not our...
New
spammy
I’m looking to build a personal workflow to quickly deploy web applications written in elixir/phoenix, for local consumption (ie not on t...
New
yureehuh
Introduction Founded in 2017 by landscape ecologist and fire mitigation expert Harry Statter, Frontline developed the first fully integra...
New

We're in Beta

About us Mission Statement