Contra

Untested

NES · 1988 · Run and gun · Decompilation

Two commandos, one jungle, thirty lives if you know the code.

▶ Play with your filesYour own Contra (USA) ROM. The 131,072-byte ROM body must hash sha1 979494e7869ac7ab4815fdbd1dc99f893f713fbf; a plain iNES or a NES 2.0 header are both accepted and identify the same cartridge. It is read in your browser and never uploaded.
Controls
Arrow keysmove and aim
XA (jump)
ZB (fire)
EnterStart
ShiftSelect
Gamepadany standard controller, detected automatically (untested)
TouchEmulatorJS on-screen NES pad on phones and tablets (untested)

About this build

Contra built from the vermiceli/nes-contra-us disassembly. The build is byte-identical to the retail Contra (USA) cartridge — the 131,072-byte ROM body hashes sha1 979494e7869ac7ab4815fdbd1dc99f893f713fbf — and runs in the browser on a WebAssembly build of the fceumm NES core. You supply your own ROM: it is read in your browser with the File API, SHA-1'd to identify the dump, and handed straight to the emulator. The page's Content-Security-Policy permits no remote origin at all, so your file cannot leave the tab even if something on the page tried to send it.

Built from
the vermiceli/nes-contra-us disassembly, assembled with cc65 (ca65/ld65) to a byte-identical ROM and run on EmulatorJS 4.2.3 with the fceumm libretro core (WebAssembly)
Type
Decompilation
Game files
Your own Contra (USA) ROM. The 131,072-byte ROM body must hash sha1 979494e7869ac7ab4815fdbd1dc99f893f713fbf; a plain iNES or a NES 2.0 header are both accepted and identify the same cartridge. It is read in your browser and never uploaded.
Code licence
vermiceli/nes-contra-us; cc65 zlib; EmulatorJS GPL-3.0; fceumm core GPL-2.0
Assets
None distributed — the player supplies their own ROM
Source
vermiceli/nes-contra-us ↗

What has been tested

Byte-exact reassembly: 0 of 131072 ROM body bytes differ from the staged dump, and upstream's own build script reports 'File integrity matches'; the two files differ only in 4 iNES-header bytes (NES 2.0 vs plain iNES). Upstream's documented md5 and sha512 were both confirmed against the ROM body before building. In the browser, audio muted throughout and 33/33 checks passing on three consecutive runs: the ROM is read from a real <input type=file> and identified by a page-computed sha1 that the driver cross-checks against the file on disk; zero off-site requests, zero request bodies and zero HTTP errors observed at the CDP network layer, with a Content-Security-Policy as the enforcing boundary; canvas asserted non-zero; and real gameplay confirmed from the game's own work RAM (GAME_ROUTINE_INDEX 5, LEVEL_ROUTINE_INDEX 4, DEMO_MODE 0, P1_NUM_LIVES 2), at addresses taken from the cc65 .dbg file this build emitted, because Contra's attract demo is screenshot-identical to play. Strongest check: from one save state, holding Right moved the player +1.00 px/frame and restoring the same state and holding Left moved him the other way. A save state survived a page reload and the game resumed at the exact position it was saved at. No level was cleared and none was attempted.

Last tested 2026-10-05 in Chrome 151 (headless, software GL). Full playthrough: not verified. How games are tested.

Known limitations

Saves

Contra has no battery save — the cartridge has no save chip, which is why the game itself has no save feature. This page instead keeps an emulator save state in your browser, under this site's storage, keyed by your ROM's own SHA-1; it is written every 10 seconds and restored when you come back. It is a save state, not a battery save, and clearing site data removes it.

Play next