Skip to content

The high-performance, preservation-focused emulation engine powering Koin Deck. Built for those who remember blowing into cartridges, but demand the convenience of the cloud.

License

Notifications You must be signed in to change notification settings

muditjuneja/koin

Repository files navigation

koin.js

Browser Retro Game Emulation for React

28 systems. Cloud saves. Multi-language. Zero backend required.

Try the Demo NPM Version License

The drop-in React component for browser-based retro game emulation. Built on Nostalgist.js, adding production-ready features like cloud saves, touch controls, gameplay recording, and RetroAchievements.

koin.js

Features

๐ŸŽฎ Core Emulation

  • 28 Consoles โ€” NES to PlayStation, Game Boy to Dreamcast
  • Automatic Core Selection โ€” Best emulator core per system
  • BIOS Management โ€” Multi-file BIOS support with UI selection
  • Performance Optimized โ€” SharedArrayBuffer for maximum speed

โ˜๏ธ Save System

  • Slot-Based Saves โ€” Multiple save states with screenshots
  • Auto-Save โ€” Periodic background saves (configurable interval)
  • Emergency Saves โ€” Automatic save on tab hide/close
  • Cloud-Ready API โ€” Bring your own backend with async handlers

๐ŸŽจ Display & Effects

  • 10 CRT Shaders โ€” Lottes, Geom, Easymode, Hyllian, zFast, and more
  • Runtime Shader Switching โ€” Change filters without restart
  • System Theming โ€” Per-console accent colors
  • Screenshot Capture โ€” PNG snapshots with hotkey support

๐Ÿ•น๏ธ Controls

  • Keyboard Remapping โ€” Per-console custom key bindings
  • Gamepad Support โ€” Auto-detect Xbox, PlayStation, Nintendo controllers
  • Touch Controls โ€” GPU-accelerated virtual D-pad and buttons for mobile
  • Control Persistence โ€” Saves user preferences across sessions

โช Special Features

  • Rewind โ€” Time-travel gameplay (auto-enabled for 8/16-bit)
  • Speed Control โ€” 0.25x to 4x with hotkey toggle
  • Fast-Forward โ€” Turbo mode for grinding

๐Ÿ“น Recording & Overlays

  • Gameplay Recording โ€” VP9/VP8 WebM capture at 30fps
  • Performance Overlay โ€” FPS, frame time, memory stats
  • Input Display โ€” Virtual controller overlay for streaming
  • Toast Notifications โ€” Non-intrusive save/load feedback

๐Ÿ† RetroAchievements

  • Official RA Integration โ€” Track unlocks across sessions
  • Hardcore Mode โ€” Disable saves/cheats for leaderboard eligibility
  • Achievement Browser โ€” Filter by locked/unlocked status
  • Progress Tracking โ€” Points remaining per game

๐ŸŒ Internationalization

  • 3 Built-in Languages โ€” English, Spanish, French
  • Type-Safe Translations โ€” Full TypeScript support
  • Partial Overrides โ€” Customize specific strings
  • Custom Languages โ€” Implement your own translation set

๐ŸŽฏ Developer Experience

  • TypeScript First โ€” Complete type definitions
  • Zero Config โ€” Works out of the box
  • Customizable UI โ€” Accent colors, shaders, controls
  • Web Component โ€” Use without React

Installation

npm install koin.js
# or
yarn add koin.js
# or
pnpm add koin.js

Quick Start

import { GamePlayer } from 'koin.js';
import 'koin.js/styles.css';

export default function App() {
  return (
    <GamePlayer
      romId="game-123"
      romUrl="/roms/mario.nes"
      system="NES"
      title="Super Mario Bros."
    />
  );
}

Cloud Integration

import { GamePlayer } from 'koin.js';

<GamePlayer
  romId="game-123"
  romUrl="/roms/game.nes"
  system="NES"
  title="My Game"
  
  // Cloud save handlers
  onSaveState={async (slot, blob, screenshot) => {
    await fetch(`/api/saves/${slot}`, {
      method: 'POST',
      body: blob,
    });
  }}
  onLoadState={async (slot) => {
    const res = await fetch(`/api/saves/${slot}`);
    return res.ok ? await res.blob() : null;
  }}
  onAutoSave={async (blob, screenshot) => {
    await fetch('/api/autosave', { method: 'POST', body: blob });
  }}
  
  // Customization
  systemColor="#FF3333"
  shader="crt/crt-lottes"
  initialLanguage="es"
/>

Internationalization

<GamePlayer
  initialLanguage="es"  // Spanish UI
/>

// Or provide custom translations
import { en } from 'koin.js';

<GamePlayer
  translations={{
    controls: {
      ...en.controls,
      play: 'START GAME',
    }
  }}
/>

Web Component

<script src="https://unpkg.com/koin.js/dist/web-component.global.js"></script>

<retro-game-player
  rom-url="./game.nes"
  system="nes"
  title="My Game"
  rom-id="game-1"
></retro-game-player>

Supported Systems

System Key Core
NES / Famicom NES fceumm
Super Nintendo SNES snes9x
Nintendo 64 N64 mupen64plus_next
Game Boy / Color GB, GBC gambatte
Game Boy Advance GBA mgba
Nintendo DS NDS desmume
PlayStation PS1 pcsx_rearmed
PSP PSP ppsspp
Sega Genesis / Mega Drive GENESIS genesis_plus_gx
Sega Master System MASTER_SYSTEM gearsystem
Game Gear GAME_GEAR gearsystem
Sega Saturn SATURN yabasanshiro
Sega Dreamcast DREAMCAST flycast
Sega CD SEGA_CD genesis_plus_gx
Neo Geo NEOGEO fbalpha2012_neogeo
Arcade (FBNeo) ARCADE fbneo
Atari 2600 ATARI2600 stella
Atari 7800 ATARI7800 prosystem
Atari Lynx LYNX handy
PC Engine / TurboGrafx-16 PCE mednafen_pce
WonderSwan / Color WS, WSC mednafen_wswan
Virtual Boy VB mednafen_vb
Vectrex VECTREX vecx
Commodore 64 C64 vice_x64
DOS DOS dosbox_pure

Full system details โ†’

Requirements

COOP/COEP Headers Required for SharedArrayBuffer:

// next.config.js
async headers() {
  return [{
    source: '/:path*',
    headers: [
      { key: 'Cross-Origin-Opener-Policy', value: 'same-origin' },
      { key: 'Cross-Origin-Embedder-Policy', value: 'require-corp' },
    ],
  }];
}

Documentation

License

MIT ยฉ Mudit Juneja

About

The high-performance, preservation-focused emulation engine powering Koin Deck. Built for those who remember blowing into cartridges, but demand the convenience of the cloud.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Languages