touchHLE is a high-level emulator for iPhone OS apps. It runs on modern desktop operating systems and Android, and is written in Rust.
touchHLE’s high-level emulation (HLE) approach differs from low-level emulation (LLE) in that it does not directly simulate the iPhone/iPod touch hardware. Instead of running iPhone OS inside emulation, touchHLE itself takes the place of iPhone OS and provides its own implementations of the system frameworks (Foundation, UIKit, OpenGL ES, OpenAL, etc). The only code the emulated CPU executes is the app binary and a handful of libraries.
The goal of this project is to run games from the early days of iOS:
- Currently: iPhone and iPod touch apps for iPhone OS 2.x.
- Next: iPhone OS 3.0 support.
- Longer term: iPhone OS 3.1, iPad apps (iPhone OS 3.2), iOS 4.x, …
- Never: 64-bit iOS.
Support for apps that aren’t games isn’t a priority: it’s more complex and less fun.
The touchHLE app compatibility database tracks which apps work in touchHLE. It is a crowdsourced effort to which anyone can contribute.
If you’re curious about the history and motivation behind the project, you might want to read the original announcement. For an introduction to some of the technical details, check out touchHLE in depth.
This project is not affiliated with or endorsed by Apple Inc in any way. iPhone, iOS, iPod, iPod touch and iPad are trademarks of Apple Inc in the United States and other countries.
Only use touchHLE to emulate software you have obtained legally.
- Officially supported: x64 Windows, x64 macOS and AArch64 Android.
- These are the platforms with binary releases.
- If you’re an Apple Silicon Mac user, the x64 build reportedly works in Rosetta.
- Probably works, but you must build it yourself: AArch64 macOS, x64 Linux, AArch64 Linux.
- Never?: other architectures.
- For simulated touch input, there are four options:
- Mouse/trackpad input (tap/hold/drag by pressing the left mouse button)
- Virtual cursor using a game controller (move the cursor with the right analog stick , and tap/hold/drag by pressing the stick or the right shoulder button)
- Mapping of game controller buttons (see the description of
- Real touch input, if you’re on a device that has a touch screen
- For simulated accelerometer input, there are two options:
- Tilt control simulation using the left analog stick of a game controller
- Real accelerometer input, if you are using a phone, tablet or some other device with a built-in accelerometer (TODO: support game controllers with accelerometers)
- This apparently doesn’t work on certain Android devices, particularly Xiaomi/MIUI devices, but we don’t know why
Real development started in December 2022. This is so far a single person‘s full-time passion project; please consider helping me to keep doing this by donating! There are also a number of volunteers contributing in their free time. There’s only been a handful of releases so far and no promises can be made about the future. Please be patient.
In general, the supported functionality is defined by the supported apps: most contributors are interested in getting a particular game working, and contribute support for whichever missing features are needed for that game. Consequently, the completeness varies a lot between APIs, e.g. UIKit is easily the most hacky and incomplete of the large frameworks that have been implemented, because most games don’t use very much of its functionality, whereas the OpenGL ES and OpenAL implementations are probably complete enough to cover a large number of early apps, because games make heavy use of these.
First obtain touchHLE, either a binary release or by building it yourself (see the next section).
You’ll then need an app that you can run. The app compatibility database is a good guide for which versions of which apps are known to work, but bear in mind that it may contain outdated or inaccurate information. Note that the app binary must be decrypted to be usable.
There’s a few ways you can run an app in touchHLE.
Special Android notes
Windows, Mac and Linux users can skip this section.
On Android, only the graphical user interface (app picker) is available. Therefore, you must put your “.ipa” files or “.app” bundles inside the “touchHLE_apps” directory. Note that you can only do that once you have run touchHLE at least once.
File management can be tricky on Android due to restrictions introduced by Google in newer Android versions. One of these methods may work:
- If you tap the “Open file manager” button in touchHLE, this should open some sort of file manager. You might also be able to find touchHLE in your device’s file manager app (often called “Files”), alongside cloud storage services. There are some limitations on what kinds of operations are possible. The files in this location are stored on your device.
- If you have an older version of Android, you may be able to directly access touchHLE’s files by browsing to
/sdcard/Android/data/org.touchhle.android/files/touchHLE_apps. Note that the
/sdcarddirectory is usually not on the SD card.
- You may be able to use ADB. If you’re unfamiliar with ADB, try using https://yume-chan.github.io/ya-webadb/ (in Google Chrome or another browser with WebUSB) with your device connected over USB. touchHLE’s files can be found in “sdcard” > “Android” > “data” > “org.touchhle.android” > “files” > “touchHLE_apps”.
Graphical user interface
touchHLE has a built-in app picker. If you put your
.ipa files and
.app bundles in the
touchHLE_apps directory, they will show up in the app picker when you run touchHLE.
To configure the options, you can edit the
touchHLE_options.txt file. To get a list of options, look in the
Command-line user interface
This section does not apply on Android.
You can see the command-line usage by passing the
If you’re a Windows user and unfamiliar with the command line, these instructions may help you get started:
- Move the
.appbundle to the same folder as
- Hold the Shift key and right-click on the empty space in the folder window.
- Click “Open with PowerShell”.
.appas appropriate) and press Enter. If you want to specify options, add a space after the app name (outside the quotes) and then type the options, separated by spaces.
Any data saved by the app (e.g. saved games) are stored in the
If the emulator crashes almost immediately while running a known-working version of a game, please check whether you have any overlays turned on like the Steam overlay, Discord overlay, RivaTuner Statistics Server, etc. Sadly, as useful as these tools are, they work by injecting themselves into other apps or games and don’t always clean up after themselves, so they can break touchHLE… it’s not our fault. 😢 Currently only RivaTuner Statistics Server is known to be a problem. If you find another overlay that doesn’t work, please tell us about it.
Building and contributing
Please see the BUILDING.md, DEBUGGING.md and CONTRIBUTING.md files in the git repo.
touchHLE © 2023 hikari_no_yume and other contributors.
The source code of touchHLE itself (not its dependencies) is licensed under the Mozilla Public License, version 2.0.
Due to license compatibility concerns, binaries are under the GNU General Public License version 3 or later.
For a best effort listing of all licenses of dependencies, build touchHLE and pass the
--copyright flag when running it, or click the “Copyright info” button in the app picker.
Please note that different licensing terms apply to the bundled dynamic libraries (in
touchHLE_dylibs/) and fonts (in
touchHLE_fonts/). Please consult the respective directories for more information.
We stand on the shoulders of giants. Thank you to:
- Everyone who has contributed to the project or supported it financially.
- The authors of and contributors to the many libraries used by this project: dynarmic, rust-macho, SDL, rust-sdl2, stb_image, Imagination Technologies’ PVRTC decompressor, openal-soft, hound, caf, dr_mp3, RustType, the Liberation fonts, the Noto CJK fonts, rust-plist, gl-rs, cargo-license, cc-rs, cmake-rs, cargo-ndk, cargo-ndk-android-gradle, and the Rust standard library.
- The Skyline emulator project (RIP), for writing the tedious boilerplate needed to replace file management on newer Android versions.
- The Rust project generally.
- The various people out there who’ve documented the iPhone OS platform, officially or otherwise. Much of this documentation is linked to within this codebase!
- The iOS hacking/jailbreaking community.
- The Free Software Foundation, for making libgcc and libstdc++ copyleft and therefore saving this project from ABI hell.
- The National Security Agency of the United States of America, for Ghidra.
- GerritForge for providing free Gerrit hosting to the general public, including us.
- The many contributors to Gerrit.
- Many friends who took an interest in the project and gave suggestions and encouragement.
- Developers of early iPhone OS apps. What treasures you created!
- Apple, and NeXT before them, for creating such fantastic platforms.
Is it okay to use runBlocking?
In this video I’ll talk about when it’s fine to use the runBlocking function from Kotlin coroutines and when you...
Mobile App Development Best Practices – 07.12
KSP2 Preview, Mastering in SwiftUI, How to implement gamification and more!
Gemini is the new foundation for artificial intelligence in Android
Foundation models are trained on a variety of data sources to create artificial intelligence systems that can adapt to a...
Google has released AlphaCode 2 based on Gemini
Google today, along with its Gemini artificial intelligence model, unveiled AlphaCode 2, an improved version of the AlphaCode code generator...
ColorfulX – Metal for crafting multi-colored gradients
ColorfulX is an implementation using Metal for crafting multi-colored gradients. ColorfulX Platform UIKit and AppKit platforms are generally supported. Due to MTKView not...
Mobile App Development Best Practices – 06.12
Power of enums, A New Foundation for AI on Android, developer dogmas and more!