Four ways to run a module on a phone
An institution gives a person its records, and a screen to read them with. That code has to run on the person's phone. Who runs it decides three things, and those three pull against each other.
Four ways, all of them built and measured on real devices. The institution's code and its package never change.
Three things that pull against each other
Weight
What the institution has to hand over, and what the person's phone has to carry.
Containment
Whether a module can reach anything that is not its own.
What the app stores allow
Apple and Google publish rules about running somebody else's code inside your app. Whether a way fits them is not a matter of opinion — it is written down.
Load the institution's code straight into Mymi and it is as light as anything gets — and nothing is keeping it apart from anyone else's. Run it in the phone's browser instead and it is kept apart and the store is happy, but now the institution has to hand over 11.3 MB instead of a quarter of one.
Each way below wins two of the three and loses one. The last two stop losing.
This is a phone problem. On a computer there is no app store to satisfy, and the operating system already keeps programs apart. That is why the last two exist only on the phone.
The four ways
Hosted
The phone's browser runs it, with a runtime of its own.
The institution's own web app, the same one it publishes, inside a view Mymi opens for it. Mymi is the postman: it brings the records and hands them over.
The browser keeps it apart, and a rule stops it reaching the network at all. This is the one that fits what the stores have written down.
What it costs is weight.
- Served per module
- 11.3 MB — 89 % runtime, 9 % engine, 3 % the institution
- Memory per open module
- ~42 MB, of which 28.5 is the runtime
- From tapping to an answer
- 1.4 s, credential and fetch included
- Modules open at once
- one
- Where it runs
- the desktop window, Android and iPhone
Working on Android and on an iPhone.
Hybrid
The browser runs the face. Mymi runs the rules, and lends the engine.
The two halves split. The institution writes its screen as an ordinary web page, and its rules as code that Mymi loads. Both travel in one package.
The weight collapses, and what left is not the engine. It is the whole runtime — 88.8 % of the hosted package against the engine's 8.6 %.
What it does not fix is the stores. The rules still run as ordinary code on the phone, so the objection stays exactly where it was. This is lighter, not more acceptable.
- The package, built 24 Sep
- 12.6 MB hosted → 0.24 MB hybrid — 45× smaller
- Unpacked, that is
- 554 KB — 283 KB the institution's rules, 254 KB its screen
- Installed on a phone
- 477 KB for the lab's module (16 Sep)
- What actually left
- the whole runtime, 88.8 % of the hosted package — not the engine, which was 8.6 %
- Memory per module
- 8–9 MB, against 42 — the runtime is paid once
- Records delivered
- 26 of 26, in 517 ms
- Where it runs
- the desktop window and Android — not yet measured on iPhone
Working since 17 September. All five apps of the ecosystem have a hybrid face, in Spanish and English, and it runs in the desktop window too — the recordings on the Mymi page were made with it.
The box
The same package, byte for byte — but the rules run inside a sandbox.
Not a different package and not a different build. The identical hybrid module, with its rules running inside a sandbox that Mymi opens for it.
Keeping it apart stops being something a person checked and becomes something the code cannot get around. It has no way to ask the system for anything, and the only things it can open are the folders Mymi hands it. The neighbour's records are not forbidden. They are not there.
And it is the same program. A history written the ordinary way replays identically inside the sandbox — the same records, the same value out of range, the same place in the list.
The engine and the runtime are built once and shared, so five modules run at the same time over one of them, with nothing rebuilt.
- Attempts to get out
- 7 of 9 succeed in-process · 8 of 8 closed in the box
- Speed against native
- 1.4–1.6× slower — a fraction, not an order of magnitude
- The shared mould
- ~94 MB once, and ~26 MB per box
- Mymi's own app
- 24 MB → 53 MB to carry it
- Where it runs
- Android
Built and working since 22 September, switched off by default. On Android.
The hall
One runtime for all of them, inside the phone's own web engine.
One page that belongs to Mymi, carrying the runtime and the engine. Each institution's rules arrive as bytes and all of them run in the same place.
The phone's own web engine keeps it apart, and the only place it can reach is itself.
The cost is that only one history can be open at a time, so a module that was set aside has to be woken up again.
- The institution hands over
- 200 KB, against 11.3 MB hosted
- Five modules loaded
- 4.1 MB each over a shared 46 MB
- The whole thing, five alive
- 151–164 MB, against 238 MB with one hosted module
- First answer, engine start included
- 440 ms · waking a module set aside, 4.15 s
- On Android
- a question answered in 380 ms cold, 5 ms warm
- On iPhone
- the document starts in ~0.9 s · the institution's rules load in 506 ms, then 53–102 ms
- Where it runs
- Android and iPhone
Built and working since 23 September, switched on one module at a time rather than by default. Measured on Android and on iPhone.
What one institution's module can reach
A person connects a lab, a supermarket, an insurer. Each one hands over a module, and each module runs on the same phone. The arrangements differ most in what one of them can touch.
Full trust. Of nine attempts to get out of a module's own folder, seven succeed. The separation is a matter of review, not of mechanism.
The browser's own separation by origin, plus a policy that forbids the module from reaching the network at all. It cannot call home, and it cannot call anywhere else.
Eight of eight attempts closed. WebAssembly has no system calls, and the only things a module receives are the folders Mymi hands it — so the neighbour's records are not forbidden, they are not reachable.
Contained by the web engine the phone already has, on a policy where the only reachable origin is its own. Fifteen assertions in the test suite cover the separation, the eviction and the refresh.
What none of them change: the records stay on the person's device. Mymi is the only piece that goes to the internet, and there is no copy of anybody's records on our side to protect in the first place.
On a desktop, the pressure is different
Mymi's desktop window runs three of the same shells, and it was where the work started — the Host loading an institution's rules into itself, which is the lightest thing on this page and the one no store would accept.
- Loaded into the Host itself
- 6.7 MB with its own engine → 16.9 KB on a lent one
- The window also runs
- the hosted shell and the hybrid one
- Containment
- the operating system's, through a child process
Two corners of the trilemma are missing here. There are no app-store terms to satisfy here, and containment is something the operating system already answers. The sandbox and the shared document were built for the pressure the phone applies — on a desktop they are not wired to the window today.
The four, side by side
| who runs the institution's code | it hands over | memory per module | what one module can reach | app stores | runs on | |
|---|---|---|---|---|---|---|
| Hosted | the browser, on its own runtime | 11.3 MB | ~42 MB | by origin | yes | desktop · Android · iPhone |
| Hybrid | Mymi the rules, the browser the face | 0.24 MB packaged | 8–9 MB | as in-process | no | desktop · Android |
| The box | a sandbox inside Mymi, shared substrate | the same hybrid package | ~26 MB + 94 MB once | 8 of 8 leaks closed | yes | Android |
| The hall | the phone's web engine, one runtime for all | 200 KB | 4.1 MB + 46 MB once | by the document's origin | yes | Android · iPhone |
“The box” and “the hall” are working names, used here because they say what each one is.
What this does not say
- No arrangement here is the final one. Two of them satisfy the store rule and contain by mechanism rather than by review; which one Mymi ships, or whether it ships both, is not decided.
- The box is switched off. It is built and it is not running for anyone.
- The hall is switched on one module at a time, not by default. Nothing turns it on for a person on its own.
- No store has accepted anything. Nobody has published. What exists is a reading of the stores' own published terms, on a date — and against Apple's it is open for all three of the contained arrangements.
- The sandbox has not been measured on an iPhone. A path for it exists; no figure on this page came from one.
- Every figure above was measured on a real device. None of them is a projection.
The module never changed
The package a hybrid institution ships is the same file in the second arrangement and in the third. Nobody rewrote it to put it in a sandbox, and nobody will rewrite it to move it again.
Four ways to run the same module on a phone — and the institution's code and package never changed.
Meet Mymi