NES emulator for the browser (JavaScript + Vite).
Live Demo: https://jsnes.dev/
- Load local
.nesROM files from a folder picker. - Mapper support: NROM (000), MMC1 (001), UNROM (002), CNROM (003).
- Quick Save / Quick Load with slot selector (SLOT 0-9).
- Quick states are persisted in IndexedDB per ROM + slot.
- Battery SRAM (in-game save data) auto-save/auto-load via IndexedDB.
- Battery save export/import as
.savfiles.
Two save systems are available and they are independent:
- Quick State
- Buttons:
Q-SAVE,Q-LOAD - Scope: full emulator runtime state
- Storage: IndexedDB (per ROM + selected quick slot)
- Battery Save (SRAM)
- Scope: in-game save data (for games that use SRAM)
- Storage: auto-managed IndexedDB entry (dedicated internal battery slot)
- File IO:
BATT EXPORT,BATT IMPORTfor.sav
- Open the app.
- Click
LOAD ROM FOLDER. - Select a local directory containing
.nesfiles. - Click a ROM in the list to start.
- Use
RESETto restart the currently running game.
| NES | Keyboard |
|---|---|
| Move | Arrow keys |
| A Button | Z |
| B Button | X |
| Start | Enter |
| Select | Space |
| Emulator Quit (debug) | Q |
| Emulator Reset (hotkey) | R |
Install dependencies:
npm install
Run dev server:
npm run dev
Build:
npm run build
Preview production build:
npm run preview
- Folder loading uses the File System Access API (
showDirectoryPicker), which is best supported in Chromium-based browsers. - Save data is origin-scoped. Clearing browser site data removes IndexedDB saves.
MIT. See LICENSE.











