A headless NES emulator core in Go. Zero dependencies, deterministic, cycle-accurate. You embed it as a Go library and drive it in-process. The UI, rewind and tooling are yours to build on top.
There is no window, no audio device, no scripting engine. Just the core and its primitives.
- Frame and instruction stepping: run a frame, single-step an instruction, reset.
- Video and audio every frame: a 256x240 buffer of NES color indices
and a block of
float32samples, plus ready-made RGBA and PCM conversion for frontends. - Memory access: peek (no side effects), poke, block reads.
- Save states: save and restore the whole console as a blob. That's all you need to build rewind and save-slots.
- Debugger: breakpoints, watchpoints, disassembly, nestest-format trace.
- Live patching: edit RAM, ROM and mapper registers while the game runs.
- Regions: NTSC, PAL and Dendy, auto-detected from the header and a built-in cartridge database (which corrects dumps that misreport their region), and overridable at runtime.
Window, audio output, key mapping, rewind and scripting are left out on purpose. They're policy, and they all fall out of the primitives above.
go get github.com/danielgatis/go-headless-nesAs a library:
import "github.com/danielgatis/go-headless-nes/nes"
console, _ := nes.NewConsole(rom)
console.RunFrame()
video := console.Video() // 256*240 NES color indices
audio := console.Audio() // float32 samplesEach Console is one independent instance, so N emulators are just N
values. A Console is not safe for concurrent use; drive each from a
single goroutine. A full runnable client lives in
docs/CLIENT.md.
To run the tests:
git submodule update --init # fetch the test ROMs
go test ./... # everything runs, no external depsA complete desktop frontend on Ebitengine,
with video, audio and keyboard, lives in
examples/nes. It is its own Go module, so the
Ebitengine dependency never touches the core's go.mod:
cd examples/nes && go run . game.nes- Go client: a minimal consumer, end to end.
- Architecture: layers, timing model, determinism.
- Mappers: the full supported list.
Copyright (c) 2026-present Daniel Gatis
Licensed under MIT License
Liked some of my work? Buy me a coffee (or more likely a beer)
