Learn ← All posts
Post

One UI, two phones

mobile · webview · app

No native build. A web app wrapped for Android and added to the home screen on iPhone.

The console I use from my phone is a single web app. On Android it ships as an APK; on iPhone it is a bookmark on the home screen. Same HTML, same CSS, same JavaScript.

Android: a thin wrapper

The APK is built with MIT App Inventor — a WebViewer pointed at the domain and a handful of blocks. That is deliberate. No native toolchain on my machine, no SDK updates, no store review. Installing a new version means moving a file to the phone.

A WebView is not a browser tab, and the differences are the actual work:

  • No native confirm(). Every confirmation is an in-page modal. Dialogs are markup, not window.confirm.
  • Downloads don't work. They go through a bridge: the page calls AppInventor.setWebViewString("open:<URL>") and the app opens it in the real browser. With no bridge present it falls back to window.open, so the same page still works in Safari and desktop Chrome.
  • Back is not free. Without a back-pressed block, the back gesture exits the app instead of moving through the UI.
  • Inputs must be 16px or larger. Anything smaller and mobile Safari zooms the page on focus, and Android keyboards shove the layout around.

iPhone: the home screen is the install

Safari → Share → Add to Home Screen. A web manifest and an apple-touch-icon are enough to get the right name and icon, and it launches without browser chrome.

Layout, on both

  • A bottom tab bar on narrow screens, safe-area insets respected, tap targets at least 44px.
  • Tables become cards instead of scrolling sideways.
  • A phone keyboard has none of the keys a terminal needs, so Esc, Tab, Ctrl, the arrows, | and ~ are buttons. Ctrl applies to the next character typed.
  • When the keyboard is up, the last line of output stays visible.

What it cost

Some layout work and a bridge of maybe twenty blocks. Everything else — logic, styles, data — is written once and runs on two phones and a desktop.