Open-source project
Hydr8gon/3Beans avatar
Hydr8gon/3Beans

3Beans: a 3DS emulator that runs the whole operating system

A low-level 3DS emulator

667 stars13 forksC++GPL-3.0

At a glance

What is it?
3Beans is a GPL-3.0 low-level Nintendo 3DS emulator written in C++ that boots the home menu and runs some games by emulating the hardware rather than reimplementing the games, with software and hardware GPU rendering. It suits emulator developers studying the console architecture, and it needs your own dumped system files and accepts no pull requests.
Who is it for?
3Beans is worth building when you want to understand how the 3DS actually works, or you want an emulator whose internals you can read and modify, since the source is complete and the architecture is documented by the referenced GBATEK and 3DBrew references. It is not worth building for playing games today, since the project states it is still young with plenty of issues, CPUs are fully interpreted, and a new 3DS is much slower than an old one.
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 last received commits 79 days ago.
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

What low-level emulation actually means here

3Beans emulates the 3DS at a low level, which the README explains means it runs the entire OS as if it were on real hardware. That single sentence is the whole design.

The contrast is with a high-level emulator, which re-implements the behaviour of individual games directly on the host CPU and never runs the console's operating system. A low-level emulator has no per-game code. It has a CPU, a GPU, memory, I/O and DSP that behave like the real hardware, and the real operating system runs on top of that, unmodified. The home menu is not special-cased. It is the same firmware that runs on a real console, executing on emulated ARM cores.

The state of the project is stated plainly: it can boot the home menu and launch some games, but it is still young and has plenty of issues. The stated goal is to achieve viable speeds with full low-level emulation, and maybe to explore some high-level elements down the road.

For a developer, that framing makes the project a hardware study as much as a program. The README points at GBATEK as an incomplete but useful reference for the 3DS hardware, 3DBrew as a comprehensive wiki covering high and low level details, libctru as a homebrew library showing how to interact with the OS, Teakra as the only source for newer aspects of the Teak architecture, and Corgi3DS as the first LLE 3DS emulator, whose logs helped the author debug.

Interpreted CPUs and the two GPU paths

The performance story is stated in one line: 3Beans has both software and hardware GPU rendering, but CPUs are still fully interpreted.

That asymmetry is worth understanding. A GPU in the 3DS is a PICA200, a proprietary design, and emulating it in software means rasterising geometry and running shader code on the host CPU, which is slow but portable. Hardware GPU rendering uses the host's OpenGL or Epoxy abstraction, which is fast but depends on the machine. The Makefile confirms the host-side dependency, linking against PortAudio and Epoxy through pkg-config, and the Windows build adds wxWidgets and Win32 libraries.

The CPU side is the harder half. The 3DS has two ARM11 cores and an ARM9 core, and 3Beans emulates them in a directory structure that shows the scope: src/core/arm for the processor cores, src/core/gpu for the graphics, src/core/dsp for the digital signal processor, src/core/memory for the memory map, src/core/io for the input and output devices, src/core/convert for data conversion, and src/core for the shared core.

Fully interpreted means every guest instruction is executed by host code rather than translated ahead of time or run through a JIT. That is the single biggest reason for the performance ceiling, and the reason the README recommends an old 3DS, since the new 3DS has more issues and is much slower.

The dumped files you need before anything runs

3Beans requires files dumped from a physical 3DS with homebrew access. This is the emulator convention rather than a peculiarity of this project: the firmware is copyrighted, so it is read from the user's own device rather than shipped.

The minimum set is boot9.bin, boot11.bin and nand.bin, and the README states that all of them can be obtained using GodMode9. The NAND image holds the system data, including the installed titles and the system's own settings, which is why a dump taken from one console behaves like that console rather than like a generic device.

You might also want to create sd.img, which can be any FAT-formatted image file, to serve as an SD card. These files are configured in the path settings.

One detail catches people out and is called out explicitly: 3Beans requires encrypted cartridge dumps, unlike high-level emulators which typically expect decrypted ones. GodMode9 can dump both encrypted and decrypted ROMs, so the dump has to be taken in the right mode. Getting this wrong produces a failure that looks like a broken emulator rather than a wrong dump.

Once the files are present, the README says 3Beans should function like the system they were dumped from, which is the most direct statement of the low-level philosophy: the emulator is not emulating a game, it is running the console.

Running it, the menus and the auto-boot setting

Controls are viewed and changed in the Settings menu, which for a low-level emulator is not a UI convenience but the only way to interact with the emulated system. Two menus matter.

The System menu allows booting without a cartridge, so you reach the firmware directly. The File menu selects a cartridge. And there is a Cart Auto-Boot setting, which exists for the case where you want to skip the home menu and load directly into a game.

That last option is a good illustration of how the emulator is used in practice. Since the firmware is real firmware, every launch goes through the console's own menus, which is slow and inconvenient for someone who just wants to play. Auto-boot is the escape hatch that skips the ceremony, and it is a setting in the Settings menu rather than a command line flag, which is consistent with the whole design being driven from a GUI.

The application itself is built on wxWidgets, which the build instructions name as a dependency at version 3.3.2 or higher, along with PortAudio for audio and Epoxy for the OpenGL abstraction. The frontend lives in src/desktop, separate from the emulation core in src/core, which is a clean split for a project of this size: the desktop shell is replaceable without touching the hardware emulation.

Building from source on Windows, macOS and Linux

The project is built with make, and the Makefile is the authoritative description of the toolchain. The compiler flags are -O3 with link-time optimisation, the C++ standard is c++11, and the log level is compiled in as a define:

bash
ARGS := -O3 -flto -std=c++11 -DLOG_LEVEL=0

The source list in the Makefile shows the module layout directly, with src, src/core, src/core/arm, src/core/convert, src/core/dsp, src/core/gpu, src/core/io, src/core/memory and src/desktop.

On Windows, the instructions are to install MSYS2 and run the pacman command to get gcc, pkg-config, wxWidgets 3.3 for MSW, PortAudio, libepoxy and jbigkit, then move to the project root and run make with the -j flag and nproc. The Windows branch of the Makefile adds a static flag, a WINDOWS define, the wx-config-static output, and the ole32, setupapi and winmm libraries.

On macOS and Linux, you install wxWidgets at 3.3.2 or higher, PortAudio and Epoxy on the target system, using a package manager such as Homebrew on macOS or the built-in one on Linux, then run make in the project root. The macOS branch adds a MACOS define and a headerpad flag for install names, while the Linux branch disables PIE and links OpenGL directly.

There is a flatpak path as well, through flatpak-builder with the manifest in the meta directory, and a mac-bundle script that builds a .app bundle and copies it to Applications.

Rolling releases, no pull requests, and what that means for you

The release situation is unusual and worth reading carefully. The only release listed is a rolling release, and the README says the latest builds are automatically provided via GitHub Actions and can be downloaded from the releases page. There is no version history to speak of, so there is no changelog to diff and no tag to pin.

The licence is GPL-3.0, which is the reciprocal licence and is the normal choice for an emulator. The LICENSE file is at the root of the repository, and the source is complete: src/, plus the Makefile, an icon directory and a meta directory holding the packaging manifests. Anyone can read the whole implementation.

The contributing policy is the part that will surprise people. The README states plainly that this is a personal project and the author has decided not to review or accept pull requests. The invitation is to test things, report issues, provide feedback, and donate if that helps. Nothing is mandatory.

That is a deliberate choice and it changes what the project is. There is no upstream that will merge your fix, so if you need a change, you maintain a fork, and if the upstream refactors and your fork lags, you carry that cost. The last push was on 2026-08-05, and the repository is not archived, so the work is ongoing, but the work is done in one direction only.

For a reader, this makes 3Beans more valuable as a reference implementation than as a dependency. You can read the ARM core, the GPU, the memory map and the DSP, all of them C++ you can compile, and use the project to understand how the console works without depending on a roadmap or an accepting maintainer.

Where 3Beans is the wrong tool

The first and clearest case is playing games. The project says it can boot the home menu and launch some games but is still young with plenty of issues, the CPUs are fully interpreted, and a new 3DS is much slower than an old one. If your goal is a working emulator with a library of titles, this is the wrong project, and a high-level emulator that expects decrypted ROMs will run the software you actually own far better.

The second case is hardware without a dump. The requirement for boot9.bin, boot11.bin and nand.bin from a physical 3DS with homebrew access means the emulator is unusable for anyone who does not have a console and the means to dump it. There is no alternative path, no built-in firmware, and no configuration that avoids it.

The third case is expecting to contribute. A project that does not accept pull requests cannot be extended by your team through the normal route. If your plan is to fix a bug upstream or add a feature that upstream will not take, you are maintaining a fork from day one.

The alternative worth understanding is a high-level emulator. The difference in approach is exactly the trade-off the project names: a high-level emulator re-implements each game and never runs the operating system, which is why it is fast and why it expects decrypted cartridges, while 3Beans emulates the hardware, runs the real firmware, and is correspondingly slower and requires encrypted dumps. Choose 3Beans when the question is how the console works. Choose a high-level emulator when the question is playing a game you own.

Editorial conclusion

3Beans is worth building when you want to understand how the 3DS actually works, or you want an emulator whose internals you can read and modify, since the source is complete and the architecture is documented by the referenced GBATEK and 3DBrew references. It is not worth building for playing games today, since the project states it is still young with plenty of issues, CPUs are fully interpreted, and a new 3DS is much slower than an old one. Before you start, dump boot9.bin, boot11.bin and nand.bin from your own console with GodMode9, confirm you are using encrypted cartridge dumps since the project requires them, and expect the project to decline pull requests, so treat it as a research codebase rather than a project you plan to contribute to.

Frequently asked questions

What is 3Beans and how does it differ from a high-level 3DS emulator?

3Beans emulates the 3DS at a low level, running the entire operating system as if it were on real hardware, rather than reimplementing individual games. A consequence is that it needs encrypted cartridge dumps, while high-level emulators typically expect decrypted ones.

What files do I need to run 3Beans?

At minimum boot9.bin, boot11.bin and nand.bin, all obtainable with GodMode9 from a physical 3DS with homebrew access. You might also want to create sd.img, any FAT-formatted image file, to serve as an SD card. These paths are set in the path settings.

How do I build 3Beans from source?

On macOS and Linux, install wxWidgets 3.3.2 or higher, PortAudio and Epoxy, then run make in the project root. On Windows, install MSYS2, fetch the dependencies with pacman, and run make with the -j and nproc flags.

Can I contribute code to 3Beans?

No. The README states that this is a personal project and that the author has decided not to review or accept pull requests. The invitation is to test things, report issues, provide feedback, and donate if that helps.

What licence is 3Beans released under and how are builds distributed?

The project is GPL-3.0 licensed, with the LICENSE file at the repository root. Builds for Windows, macOS and Linux are provided automatically through GitHub Actions and are downloaded from the releases page, and the only listed release is a rolling release.

Official sources

  1. Hydr8gon/3Beans on GitHub
  2. Issues
  3. License: GPL-3.0
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/hydr8gon-3beans.svg)](https://hysenlabs.com/projects/hydr8gon-3beans)

Was this useful?