A UI-focused entry in TopGit's GitHub warehouse: bfirsh/jsnes, 6.4k stars, Frontend, JavaScript. A JavaScript NES emulator.
Snapshot summary built from the project's own GitHub metadata — there's no written TopGit review yet. The page will update automatically when a full review is published.
WHY NO REVIEW YET
TopGit writes full reviews for the most-starred, most-requested repositories. This page is a snapshot until then — see the READ ME tab for the original README in full.
The easiest way to use JSNES in a web page is with jsnes.Browser. It handles canvas rendering, audio, keyboard input, gamepad input, and frame timing automatically.
<div id="nes" style="width: 512px; height: 480px"></div>
<script src="https://unpkg.com/jsnes@2/dist/jsnes.min.js"></script>
<script>
var browser = new jsnes.Browser({
container: document.getElementById("nes"),
onError: function (e) {
console.error(e);
},
});
jsnes.Browser.loadROMFromURL("my-rom.nes", function (err, data) {
if (err) {
console.error(err);
return;
}
browser.loadROM(data);
});
</script>
If you already have ROM data as a string or byte array, you can pass it directly:
var browser = new jsnes.Browser({
container: document.getElementById("nes"),
romData: romData,
});
See Keyboard Controls below for default key bindings. Gamepads are also supported automatically.
A complete embedding example is in the example/ directory. You can try it by running npx serve . in the repository root and opening http://localhost:3000/example/nes-embed.
A full-featured React frontend is available in the web/ directory of this repository.
Node.js / custom integration
If you need lower-level control (custom rendering, audio handling, or running in Node.js), use the NES class directly:
// Initialize and set up outputs
var nes = new jsnes.NES({
onFrame: function(frameBuffer) {
// ... write frameBuffer to screen
},
onAudioSample: function(left, right) {
// ... play audio sample
}
});
// Read ROM data from disk (using Node.js APIs, for the sake of this example)
const fs = require('fs');
var romData = fs.readFileSync('path/to/rom.nes', {encoding: 'binary'});
// Load ROM data as a string or byte array
nes.loadROM(romData);
// Run frames at 60 fps, or as fast as you can.
// You are responsible for reliable timing as best you can on your platform.
nes.frame();
nes.frame();
// ...
// Hook up whatever input device you have to the controller.
nes.buttonDown(1, jsnes.Controller.BUTTON_A);
nes.frame();
nes.buttonUp(1, jsnes.Controller.BUTTON_A);
nes.frame();
// ...
API Reference
NES
var nes = new jsnes.NES(options);
Options:
Option
Type
Description
onFrame
function(frameBuffer)
Called at the end of each frame with a 256×240 pixel buffer (Int32Array of ARGB values).
onAudioSample
function(left, right)
Called for each audio sample with left/right channel values (-1.0 to 1.0).
onStatusUpdate
function(status)
Called with status messages (e.g. "Ready to load a ROM.").
onBatteryRamWrite
function(address, value)
Called when battery-backed SRAM is written. Use this to persist save data.
emulateSound
boolean
Enable/disable audio emulation. Default: true.
sampleRate
number
Audio sample rate in Hz. Default: 48000.
Methods:
Method
Description
nes.loadROM(data)
Load a ROM from a string, Uint8Array, or ArrayBuffer.
nes.frame()
Execute one frame of emulation. Call this at 60 fps.
nes.buttonDown(player, button)
Press a button. player is 1 or 2.
nes.buttonUp(player, button)
Release a button.
nes.reset()
Reset the emulator (like pressing the reset button on the NES).
nes.reloadROM()
Reload the current ROM from scratch.
nes.getFPS()
Get the current frames-per-second count.
nes.setFramerate(rate)
Change the target frame rate.
nes.toJSON()
Serialize emulator state (for save states).
nes.fromJSON(data)
Restore emulator state from a previous toJSON() call.
nes.zapperMove(x, y)
Move the Zapper light gun to the given pixel coordinates.
ROM data to load immediately. If omitted, call loadROM() later.
onError
function(error)
Called when the emulator encounters an error during frame execution.
onBatteryRamWrite
function(address, value)
Called when battery-backed SRAM is written.
Methods:
Method
Description
browser.start()
Start emulation. Called automatically if romData was provided.
browser.stop()
Pause emulation.
browser.loadROM(data)
Load a new ROM and start emulation.
browser.fitInParent()
Re-layout the canvas to fill its container.
browser.screenshot()
Returns an HTMLImageElement of the current frame.
browser.destroy()
Full cleanup: stop emulation, remove listeners, remove canvas.
Browser.loadROMFromURL(url, callback)
Static method. Fetch ROM data from a URL. Callback is (error, data).
Properties:
Property
Description
browser.nes
The underlying NES instance.
browser.keyboard
The KeyboardController for remapping keys.
browser.gamepad
The GamepadController for remapping gamepad buttons.
Keyboard Controls
When using jsnes.Browser, the following keyboard bindings are set up by default:
Button
Player 1
Player 2
Up / Down / Left / Right
Arrow keys
Numpad 8 / 2 / 4 / 6
A
X
Numpad 7
B
Z (or Y)
Numpad 9
Turbo A
S
—
Turbo B
A
—
Start
Enter
Numpad 1
Select
Right Ctrl
Numpad 3
Turbo A and Turbo B behave like A and B but auto-fire repeatedly while the key is held.
Key bindings can be customized at runtime via the browser.keyboard property. Use setKeys() to provide a custom mapping (persisted to localStorage) and loadKeys() to reload it:
// Get the current key map
var keys = browser.keyboard.keys;
// Remap Player 1 A button to the J key (keyCode 74)
keys[74] = [1, jsnes.Controller.BUTTON_A, "J"];
browser.keyboard.setKeys(keys);
Build
To build a distribution:
$ npm run build
This will create dist/jsnes.min.js.
Running tests
$ npm test
Formatting code
All code must conform to Prettier formatting. The test suite won't pass unless it does.
To automatically format all your code, run:
$ npm run format
Related projects
NEStation - Multiplayer NES over the internet!
Thanks
JSNES is based on James Sanders' vNES, and owes an awful lot to it. It also wouldn't have happened without Matt Wescott's JSSpeccy, which sparked the original idea. (Ben, circa 2008: "Hmm, I wonder what else could run in a browser?!")
How does bfirsh/jsnes compare to other Frontend projects?
bfirsh/jsnes is tracked by TopGit in the Frontend category, with 6.4k GitHub stars and written in JavaScript. Browse the Frontend topic page on TopGit to compare it against similar projects by stars and activity.
How many stars does bfirsh/jsnes have?
bfirsh/jsnes has 6.4k GitHub stars — refresh the page for the live number, or check github.com/bfirsh/jsnes. TopGit mirrors GitHub's count but does not claim minute-by-minute accuracy.
Is bfirsh/jsnes open source?
Yes — bfirsh/jsnes ships under the Apache-2.0 license, which makes its source code freely readable (and, depending on license terms, forkable and reusable). Source: github.com/bfirsh/jsnes.
What else is in the Frontend space?
bfirsh/jsnes is tracked by TopGit under the Frontend category, alongside 5 GitHub-tagged topics. Trending and Topics pages list peer repositories of comparable stars and language.
What is bfirsh/jsnes?
bfirsh/jsnes (bfirsh/jsnes) is a JavaScript project on GitHub. From the project's own README: A JavaScript NES emulator.
Where can I see bfirsh/jsnes in action?
The project maintains a homepage at https://jsnes.org. The README tab on this page also usually contains screenshots and a quickstart.
Where do I read more about bfirsh/jsnes?
This TopGit page is a snapshot — the READ ME tab shows the project's own README content (links stripped, images preserved). The GitHub repository at github.com/bfirsh/jsnes is the definitive source.
Read full README in the tab above.
Want a second opinion on jsnes?
Ask an AI that can read this page — one click and you get its take on jsnes.