GenericJam

GenericJam

Plugin System for Mob

Mob is growing by leaps and bounds! I realize now we will not be able to accommodate all the functionality people would want in the main framework itself. It is designed to be extensible. The build system should be able to handle plugins now.

The idea for the plugins is similar to React Native plugins. This is more than coincidence because React Native and Mob have similar architectures, with Mob being a bit simpler. The native code in Kotlin/Java, Swift/ObjC, C is likely very close to what Mob would need. The main difference is the logic is in Elixir, not JS and the distribution is hex.

One of the upsides of the similarity is we could migrate many of these to Mob which would be a big boost to the ecosystem. There are ~150-200 that land in this ‘native heavy’ category that would be very attractive to use such as date pickers, etc. that translate to native elements.

So you’d have the Android native code in /android and the iOS native code in /ios. You could have one sided plugins that only land on one platform.

I’ve brainstormed a pretty extensive document on this with Claude. Here’s the shorter summary:

Mob Plugins: Manifest Schema Proposal

Three design choices anchor this proposal. First, the manifest is data, not code — mob_dev reads priv/mob_plugin.exs at compile time rather than having plugins call register_plugin at runtime. Static, inspectable, validatable; closer to mix.exs than to Phoenix’s runtime route registration. Second, activation is explicit and separate from installation, borrowed from how iOS entitlements work: a framework supporting capability X doesn’t mean your app uses X without explicit declaration. This mitigates supply-chain risk by ensuring mix deps.get can never silently modify your app’s permission set. Third, the schema scales with plugin tier rather than being exhaustive everywhere — small plugins write three fields, large plugins write a dozen sections, and the shape of the manifest doesn’t make trivial plugins look heavy. Underlying all of this: Hex is the substrate, so versioning, dep resolution, security posture, and hexdocs publication come free, and static linking is required (no dlopen) to stay App-Store-compatible.

The schema spans five tiers. Tier-0 is a pure Elixir Hex package needing no manifest at all. Tier-1 adds NIFs and per-platform native sources — Kotlin bridge files, Swift files, Gradle deps, frameworks, permissions, plist keys. Tier-2 introduces :ui_components for new render-tree node types with paired SwiftUI views and Composables. Tier-3 layers on :screens, :migrations, and :assets for plugins that ship entire mini-applications. Tier-4 adds :lifecycle, :settings, and :notifications for embedded sub-apps with supervised children, persisted user settings, and push notification handlers. Required top-level fields are just :name, :mob_version, and :plugin_spec_version; everything else is independently optional.

Installation is deliberately two-step. Adding a plugin to deps and running mix deps.get makes it resolvable but does not merge native code, permissions, or plist keys. Activation requires an explicit entry in config :mob, :plugins in mob.exs. mob_dev prints the diff at compile time so users see exactly what’s being added — permission set changes are never silent. mix mob.add_plugin wraps both steps plus optional interactive setup prompts where plugin authors guide tier-3/4 integration (e.g., “Register MobChatKit.MessageListScreen in your App.navigation/1?”). The standard flow always works; the convenience command is not a required entry point.

Validation runs at two stages and fails loud. mix mob.validate_plugin checks the plugin in isolation: paths exist, files parse, version requirements are valid, and single-platform UI components are flagged as warnings (the #1 React Native plugin pain point). mob_dev then re-validates at compile time across all activated plugins — no duplicate component atoms, no colliding screen routes, no migration namespace collisions, all activated plugins present in deps. Hot-pushability is computed automatically from which sections are populated: tier-0 hot-pushes fully, tiers 1-2 require a native rebuild, tiers 3-4 are partial (Elixir hot-pushes; native does not). Forward compatibility is handled via :plugin_spec_version, letting the schema evolve without breaking existing plugins — bump the integer, support both versions in mob_dev for a migration window, deprecate.

Any comments or questions are appreciated.

Where Next? Top

Trending in RFCs Top

Hedgehog-ai
Hello I would like feedback on an experimental neuroevolution (including substrate encoding) library called Bardo based on the amazing wo...
New
phravins
Hey everyone , We’ve been working on an idea and wanted to share it here. If you’ve tried using Razorpay with Elixir, you’ve probably n...
New

Other Trending Topics Top

dominicletz
Hey there, I haven’t seen a list of useful Elixir specific skills for the popular AI tools yet so I’m starting one here with my first. ...
New
raa-ziq
Hi everyone :waving_hand: I wanted to share something I’ve been building — NowBlind, a random chat app designed to help people discover ...
New
mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
OndrejValenta
(I just needed to vent somewhere and LinkedIn is full of hope, or hype, I’m not sure which exactly) AI dream has many faces, but general...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews