Guides / How EmulatorJS Works

How EmulatorJS Works

By CartridgeCove Editorial Team · August 4, 2026

In short: CartridgeCove’s homebrew games run entirely in your browser through EmulatorJS, a WebAssembly-based emulator we host ourselves rather than embedding a third-party site. No plugin, no download, no account — click Play and the console core loads on demand.

Why self-host the emulator instead of embedding one

Most retro game sites — including our own sister site, CraazyGames — embed a third-party emulator page inside an iframe. That’s fast to set up, but it means the actual emulation code, and often the ROM file itself, lives on someone else’s server. If that server goes down, changes its terms, or starts serving ads inside the game frame, there’s nothing the linking site can do about it.

For CartridgeCove’s homebrew catalog — titles we’ve individually rights-cleared and can legally redistribute — we host both the emulator and the game file ourselves. That’s the trade we’re making: more setup work on our end, in exchange for a permanent, ad-free, single-domain experience for a title we know we have the right to serve.

How it actually loads

EmulatorJS ships a JavaScript loader, a set of WebAssembly emulator cores (one per console — our NES titles use a WebAssembly build of the FCEUmm core), and the game file itself. On a CartridgeCove game page, none of that loads when the page first opens. The page shows a static “Play” button; only when you click it does the loader script inject itself, fetch the correct core for that console, and start the emulator inside a designated player element.

That deferred-loading detail matters more than it sounds. An emulator core plus a game file is a few megabytes — trivial once you’ve decided to play, but if it loaded automatically on every visit it would compete with the page’s actual content for bandwidth and directly hurt Largest Contentful Paint, one of Google’s Core Web Vitals. Gating it behind a click means visitors who are just reading about a game, not playing it, never pay that cost.

What this means for you as a player

Controls default to a standard keyboard mapping (arrow keys plus Z/X/A/S for face buttons), shown on each game page, and EmulatorJS also supports a connected gamepad automatically. Save states, fullscreen, and volume controls are all built into the player’s own control bar once a game is running — we don’t customize that part, since EmulatorJS’s own interface already covers it well.