pound: A Switch Emulator Rebuilt Around a New ARM Recompiler
Open source emulator for the Nintedo Switch 1 and 2. Highly work in progress
At a glance
- What is it?
- Pound is an open source emulator for the Nintendo Switch 1 and 2, and its current direction is a rewrite of the execution engine: instead of emulating the ARM CPU instruction by instruction, the project is building Ballistic, a new recompiler that translates SM86 into SPIR-V and runs it on Vulkan, with a JIT code cache and a metadata manager planned alongside it.
- Who is it for?
- pound fits a developer who wants to work on emulation internals, especially on the compiler and JIT side, since the repository is explicit that it is looking for compiler developers to help build the recompiler. It is a poor fit for someone who wants a finished emulator today, because the project describes itself as highly work in progress and the central engine is still unchecked on the task list.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
An Emulator That Changed Its Execution Model
Pound is an open source emulator for the Nintendo Switch 1 and 2, described in the project description as highly work in progress, and the development direction is stated in capital letters at the top of the README.
The important line is that in order to squeeze as much performance as possible for Switch 1 and 2 emulators, development has fully shifted to creating a new ARM recompiler from the ground up, with a link to the separate ballistic repository, and an appeal to compiler developers to give support.
That is a large change of direction for a project and it explains the shape of everything else in the repository. An emulator that interprets ARM instructions has a cost per instruction that is hard to move, and the way past it is to translate the guest code into something the host GPU can execute directly. The plan named here is SM86, which is the Switch 2's instruction set, translated to SPIR-V, which is the intermediate representation Vulkan consumes.
So the project is no longer primarily about emulating hardware, it is primarily about writing a compiler and a JIT. That is why the repository is C, why it has a CMake build with presets, and why the task list below is dominated by memory management rather than by console features.
The Task List Is the Design Document
The README does not have a feature list. It has a checklist of six engineering tasks, and that checklist is the most informative document in the project:
Translate SM86 to SPIR-V to Vulkan
Add mimalloc for host allocator
Create a custom pool / slab allocator for Horizon OS
Create a JIT code cache memory allocator for Ballistic
Create a JIT metadata manager
Integrate Ballistic into PoundOnly one of the six is marked as done, and that one is the host allocator. So the picture at the moment is a project that has made its architectural decision and has not yet built the central piece of it.
The order of the list is a dependency order, and reading it that way is informative. The translation from SM86 to SPIR-V to Vulkan is the first and hardest item, and the last item is the integration of the recompiler into the emulator, which cannot start until the recompiler exists. The two JIT items and the custom allocator sit in between because they are the supporting machinery that the translated code needs.
The Horizon OS line is the one that surprises people who have not read the Switch internals. Horizon is the console operating system, and the request is for a custom pool or slab allocator for it, which suggests the project is not only translating user code but also modelling the allocations the guest system makes.
Why a Recompiler Instead of an Interpreter
The motivation for the rewrite is stated in one phrase, to squeeze as much performance as possible for Switch 1 and 2 emulators, and the target is a pipeline that ends in Vulkan.
The chain is worth spelling out because each stage implies a different piece of engineering. SM86 is the guest instruction set that has to be translated. SPIR-V is the intermediate representation, so the translation is a compiler front end producing a standard IR rather than something bespoke. Vulkan is the API the host GPU consumes, so the output of the JIT is a Vulkan shader rather than machine code.
Doing it this way means the emulated CPU work becomes GPU work, and the GPU is where the Switch's own performance comes from. A traditional emulator spends its time in a tight loop translating one guest instruction at a time on the CPU, and the cost of that loop is the ceiling on how well the console can be emulated.
The tradeoff is that a compiler is harder to get right than an interpreter, because a mistake in a JIT is a crash in the middle of a game rather than a wrong result in a data structure, and because the compiler has to handle the whole program rather than one instruction at a time. That is what the appeal for compiler developers is about, and it also explains the two JIT-specific tasks, since a JIT needs somewhere to put the code it generates and something to track the metadata that maps the generated code back to the guest program.
Memory: mimalloc on the Host, Slabs on the Guest, a Cache for the JIT
Three of the six tasks are about memory, and they are three different problems.
The one that is already done is mimalloc for the host allocator. The host is the machine running the emulator, and the general purpose allocator it uses is on the hot path of every allocation the emulator makes, including the allocations of the emulated system. Swapping in a faster general purpose allocator is the cheap first step, and it is marked complete.
The custom pool or slab allocator for Horizon OS is a different problem. That is the guest side, the allocations the emulated console operating system makes, and a slab or pool allocator gives the emulator a way to serve them from pre-sized blocks rather than from the host allocator one at a time, which is the standard trick for workloads with many small, same-lifetime allocations.
The JIT code cache memory allocator for Ballistic is the third, and it is the one that matters for the new architecture. A JIT produces translated code at run time, and that code has to live somewhere. Allocating it from the general purpose heap would mean paying allocator overhead and fragmentation on a path that runs constantly, so the plan is a dedicated cache with its own allocation policy, sized for the code it holds rather than for general use.
The JIT metadata manager sits alongside it, and its job is bookkeeping: the mapping between the guest program and the code that was generated for it, so that execution can be resumed at the right place and so that the cache can be invalidated when the guest program changes.
A CMake Project With Presets and a Split Source Tree
The repository layout is what you would expect for a project with a separate compiler component and a separate emulator component.
The top level holds .clang-format, so the code style is enforced mechanically, a .gitattributes file, the GitHub workflows, a CMakeLists.txt, a CMakePresets.json, the LICENSE, the README, and then the directories: cmake/ for the build configuration, docs/ for the documentation, extern/ for the third party dependencies, and src/ for the implementation. There is also a docs/ directory, which is where the design notes for a project in this state belong.
The use of CMakePresets.json is worth noting. A project that supports Linux and Windows with one toolchain, and that has to be built both standalone and as part of a larger tree, gets repetitive with raw CMake arguments, and presets encode the configurations so that a contributor can pick a named configuration instead of remembering a list of flags.
The extern/ directory is the other structural signal. A recompiler with a code generator needs its own libraries, and keeping them in extern/ rather than pulling them from a package manager at build time means the dependency set is fixed in the tree and the build is reproducible on a machine that has never seen the project before.
The Windows Gap Is the Contribution Opportunity
The Development section is short and contains the most actionable information in the repository.
Pound actively supports Linux and Windows with the Clang compiler only. The maintainer states that they cannot run Pound on Windows, so the Windows builds will fall behind the Linux builds, and asks for Windows specific contributions.
That is an unusual and useful thing for a project to say, because it converts a maintenance gap into a specific invitation. The person who knows the Windows toolchain, the debugger integration, the graphics API quirks and the path handling is the person the project needs, and the same goes for the compiler developers the overview appeals to for the Ballistic work.
The broader picture is of a project that is early in a rewrite and honest about it. The description says highly work in progress, the checklist shows one completed item out of six, and the emphasis in the README is on recruiting help rather than on announcing a usable build.
The project is licensed under GPL-3.0, it publishes no GitHub releases, and the last push was on 2026-09-11, so the tree is being worked on even though there is nothing to download.
Editorial conclusion
pound fits a developer who wants to work on emulation internals, especially on the compiler and JIT side, since the repository is explicit that it is looking for compiler developers to help build the recompiler. It is a poor fit for someone who wants a finished emulator today, because the project describes itself as highly work in progress and the central engine is still unchecked on the task list. Before contributing, read the platform note, because the maintainer works on Linux and cannot run Pound on Windows, so the Windows builds fall behind and Windows specific contributions are the gap most worth filling. The repository is GPL-3.0 licensed, it publishes no GitHub releases, and the last push was on 2026-09-11.
Frequently asked questions
What is pound?
It is an open source emulator for the Nintendo Switch 1 and 2, described as highly work in progress. The repository contains the emulator source, a CMake build, documentation and the third party sources, and no game content.
Why is pound being rewritten around a recompiler?
The README states that in order to squeeze as much performance as possible for Switch 1 and 2 emulators, development has fully shifted to creating a new ARM recompiler from the ground up, and it asks compiler developers to help. The plan is to translate SM86 to SPIR-V to Vulkan.
Which parts of the new engine are finished?
Of the six tasks listed in the README, only adding mimalloc for the host allocator is marked as done. The translation to SPIR-V and Vulkan, a custom pool or slab allocator for Horizon OS, a JIT code cache memory allocator for Ballistic, a JIT metadata manager and the integration of Ballistic into Pound are all still open.
Which platforms does pound support?
Linux and Windows, with the Clang compiler only. The maintainer says they cannot run Pound on Windows, so the Windows builds fall behind the Linux builds, and Windows specific contributions are welcomed.
How is the pound project built?
With CMake and CMakePresets.json at the repository root, with a cmake/ directory for the build configuration, an extern/ directory for third party sources, and src/ for the implementation. The project is GPL-3.0 licensed, publishes no GitHub releases, and the last push was on 2026-09-11.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/pound-emu-pound)Was this useful?