JIT & Performance
Short version. iCube runs GameCube and Wii code two ways. The JIT recompiler is several times faster but needs a debugger attached when you start a game. The Cached Interpreter needs nothing at all and is what you get by default. Both work; only one is fast.
What JIT actually is
A GameCube or Wii game is PowerPC machine code. Your iPhone is ARM. Something has to translate, and there are two ways to do it.
An interpreter reads one PowerPC instruction at a time and acts it out in software. It is simple, it always works, and it is slow, because every single instruction costs a decode and a dispatch.
A JIT recompiler (just-in-time) translates a whole block of PowerPC into real ARM instructions once, writes those into memory, and then runs them directly on the CPU. Every later visit to that block runs at native speed. That is the whole trick, and it is why JIT is worth this much effort.
The catch is that writing instructions into memory and then executing them is exactly what iOS is built to prevent. An ordinary app cannot mark memory as both writable and executable. Apple grants that ability to debuggers, so on iOS the route to JIT has always run through a debugger.
What iOS 26 changed
iOS 26 added a hardware-backed guard called the Trusted Execution Monitor. Under it, the old approach stopped working: iCube could still allocate executable memory, but the moment it jumped into freshly written code the app was killed. That is why JIT was pulled from iCube for a while and every device ran the interpreter.
The way through is narrow and specific. Under the Trusted Execution Monitor, a page of executable memory becomes runnable once a debugger has written to that page. The write itself is the permission. So iCube asks the attached debugger to touch every page of its code region once, at startup, and from then on the region is usable for the life of the app.
iCube reserves 288 MB for that region and the whole authorization pass takes a few seconds. Once it is done the debugger can disconnect and the game keeps running at full speed.
Turning JIT on (iOS / iPadOS)
On iPhone and iPad we recommend StikDebug. It runs on the device itself, so you do not need a computer every time.
- Install StikDebug and complete its one-time pairing setup.
- Open iCube and go to Settings → Debug → Environment. If your device needs JIT enabling, an Enable JIT via StikDebug button appears there.
- Tap it. iCube hands StikDebug its own broker script over the URL scheme, so there is nothing to set up inside StikDebug itself.
- StikDebug attaches and relaunches iCube. Wait for iCube to come back.
- Open a game. The code region is authorized as it boots, and JIT stays active for as long as the app keeps running.
Authorization happens once, at startup. If iCube is fully quit and relaunched, it has to be done again. It is not a setting that sticks across launches, and there is nothing iCube can do about that — the permission belongs to the debugger session, not to the app.
Checking whether it worked
Under Settings → Debug → Environment, iCube reports its own state. JIT says whether the capability was acquired, Debugger whether one is attached right now, TXM JIT Region whether the code region was authorized, and JIT Error carries the reason when something did not work.
On a working iOS 26 setup, TXM JIT Region reads Authorized. It stays that way after StikDebug disconnects, so Debugger: Not Attached alongside it is normal and not a problem.
The honest test is the frame rate. If a game that used to crawl now holds its native speed, JIT is on. If nothing changed, it is not, and iCube quietly fell back to the interpreter rather than crashing.
Running without JIT
You do not have to use JIT. iCube's default is the Cached Interpreter, which needs no debugger, no pairing and no extra app, and which has had a lot of work put into it. Lighter GameCube titles are genuinely playable on a recent device.
It will not match JIT. Demanding Wii titles in particular need the recompiler. If a game runs at a fraction of full speed without JIT, that is the interpreter doing its best, not a bug.
A newer device helps either way. An iPhone 15 Pro or later has noticeably more headroom than older hardware.
Older iOS, and tvOS
iOS 18 and earlier have no Trusted Execution Monitor, so the classic route applies: attach any JIT enabler once and iCube picks up the capability. The page-authorization pass described above is skipped entirely.
tvOS has no StikDebug and no on-device debugger, so Apple TV runs the Cached Interpreter. That is the expected behaviour, not a missing feature.
Troubleshooting
No “Enable JIT via StikDebug” button
iCube only shows it when StikDebug is actually installed, because it opens StikDebug by URL. Install StikDebug, then reopen iCube's settings.
It says a previous attempt did not complete
iCube remembers when an authorization attempt never finished and declines to repeat it on its own, so a bad setup cannot make the app fail at every launch. A Retry JIT Authorization button appears in Settings → Debug → Environment while that is in effect; tapping it, or tapping Enable JIT via StikDebug, re-arms it.
Speed went back to normal after a while
Check whether iCube was fully quit in the app switcher at some point. Authorization does not survive that. Relaunching the app means enabling JIT again.
TestFlight and App Store builds cannot do this
Attaching a debugger requires an entitlement Apple does not permit in App Store distribution, and TestFlight is App Store distribution. Those builds have JIT compiled out entirely and always run the Cached Interpreter. JIT is available on the sideloaded builds only — AltStore, SideStore or Sideloadly. See Downloads for how to install those.