A bit more regarding UTM SE on the iPad

I spent a few hours trying out (which, if you’re new here, is a version of the front-end for that runs on ) on my , and quickly came to the conclusion that it is not really usable to do local development out of the box.

It might be great to, say, run Windows 95 or older DOS games (and I’m still sore that the Mac OS 9.2.1 image vanished), but unlike the “real” , using on iOS or an iPad is severely hobbled by the lack of a JIT.

However, given my recent on how I miss better ways to do small computing, I had to push the envelope a bit and try to figure out exactly how usable it might be in a pinch, so I plugged my iPad into my LG UltraFine and tried out some stuff so that you don’t have to–and I’m throwing in a few comparisons to and iSH as well.

The Experiment

So far, being able to run arm64 binaries locally (even if apparently much slower than doing the equivalent in iSH) is ’s key differentiator for me.

Running sudo systemctl set-default multi-user.target to disable the GUI and restricting the core count to 2 on the pre-built Debian XFCE image makes it reasonably usable, and highlights a couple of nice advantages:

  • You get full Linux console emulation (and frame buffer graphics, should you need them). It can be quite slow, though.
  • I can (theoretically) install and build just about everything I need–Go, Rust, Scheme, etc. It all depends on how long I want to wait.

And it does work–here’s me building an actual binary on it:

a bit rusty
This is still amazing to see, even knowing it could be so much faster...

The main drawbacks with right now are all related to performance and integration:

  • Copy/paste currently doesn’t work at all–not even via keyboard emulation.
  • I can’t use the VM controls at all when UTM SE is on an external display, and if I move it to the iPad display, it will blank out the external display because it assumes I might want to have it as a secondary display adapter.
  • Unlike or iSH, the boot time takes a significant toll on usability–even in CLI mode, it takes almost a minute to be able to log in.
  • The almost bare CLI system, with htop running in the foreground, takes up 10% of my iPad’s CPU. Doing anything of consequence (like editing files or compiling a small binary) will shoot at least past 30% when emulating just 2 cores.
  • Installing anything takes a long time because merely decompressing the packages is very slow–this is just one example of where a JIT would make a stupendous amount of difference. My initial experience with doing an apt upgrade consumed over a tenth of my iPad’s battery solely because of that.
  • And, of course, filesystem integration is not as smooth (I’ve actually yet to get it to work, but I believe it’s there).

Alternatives

The good thing is that there are alternatives if you want a CLI on an iPad–and they’re actually surprisingly useful, even if not as popular or well-understood as they probably ought to be.

has been for almost any kind of scripting (, , etc.) on the iPad since it came out–in fact, I’m posting this from vim running inside it, and there’s very little actually lacking for a lot of simple programming tasks.

Since it is a mix of Nicholas Holzschuch’s excellent ios_system and binaries, you have a variety of packages (including the sqlite binary I contributed with Nicholas’ help), and it handles multi-tasking and multiple windows quite well (within the constraints of , of course), with minimal (almost residual) CPU usage.

Everything is very speedy, responsive and eminently useful (even if a bit quirky if you’re used to standard UNIX shells), and in all my time using it I’ve only experienced three recurring nuisances:

  • The terminal emulation is a bit temperamental (and you get an extra always-on caret for selection, which is distracting and fiddly). That shows up when using ssh sometimes, but also with anything that expects full VT100 emulation.
  • There’s no native git (it ships with lg2, which mostly works, but I have to resort to Working Copy to manage most of my code).
  • Due to the restricted environment, building your own binaries is a chore (it has to be done on a desktop machine), and you can’t really get most Python or Lua dependencies to build locally.

I’ve been able to do a lot inside it, and it is the closest to an iPad-native shell there is right now. Blink has recently begun incorporating some local binaries based on ios_system and has superior terminal emulation, but despite my liking its vim experience better due to that, it doesn’t really count as a local shell.

iSH

iSH has been around for a long time now (as such things go), and provides a restricted x86 (not 64-bit, just 32-bit) emulation environment with an Alpine Linux userland.

I’ve been using it to run fairly complex Python stuff that I just can’t get to work under locally for almost a year now (like weasyprint and other things I need for generating PDFs on the go), and it can compile most C binaries just fine, but not Go (binaries crash) or Rust (cargo panics while building), plus gdb plain doesn’t work on most occasions.

That said, even if it is still slow for an emulator (and will also impact your battery life), it is quite usable for running a lot of things, especially if they’re already available in Alpine–and it can access the iOS filesystem, too, making it a great complement for .

Using a Sidecar

As much as it pains me to keep re-stating this, getting a small Linux single-board computer and is still the best option for developing on the go on an iPad.

At least when compared to , not only will it be much faster and useful overall, the impact of not having a JIT is so great that your battery will last longer even if you power a modern quad-core SBC directly from the iPad.

So thank you Apple, yet again, for not letting us have nice things even if they would be completely sensible and greatly improve some of your most devoted users’ feelings towards your approach to, er… “supporting” developers.

This page is referenced in: