koin.js
Browser Retro Game Emulation for React
24 systems. Cloud saves. Multi-language. Zero backend required.
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.
Features
đŽ Core Emulation
- 25 Consoles â NES to PlayStation, Game Boy to Saturn
- 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 | Source |
|---|---|---|---|
| NES / Famicom | NES |
fceumm | Nostalgist |
| Super Nintendo | SNES |
snes9x | Nostalgist |
| Nintendo 64 | N64 |
mupen64plus_next | BinBashBanana |
| Game Boy / Color | GB, GBC |
gambatte | Nostalgist |
| Game Boy Advance | GBA |
mgba | Nostalgist |
| Nintendo DS | NDS |
melonds | BinBashBanana |
| PlayStation | PS1 |
pcsx_rearmed | Nostalgist |
| Sega Genesis / Mega Drive | GENESIS |
genesis_plus_gx | Nostalgist |
| Sega Master System | MASTER_SYSTEM |
gearsystem | Nostalgist |
| Game Gear | GAME_GEAR |
gearsystem | Nostalgist |
| Sega Saturn | SATURN |
yabause | BinBashBanana |
| Neo Geo | NEOGEO |
fbalpha2012_neogeo | Nostalgist |
| Arcade (FBNeo) | ARCADE |
fbneo | Nostalgist |
| Atari 2600 | ATARI_2600 |
stella2014 | BinBashBanana |
| Atari 5200 | ATARI_5200 |
a5200 | BinBashBanana |
| Atari 7800 | ATARI_7800 |
prosystem | BinBashBanana |
| Atari Lynx | LYNX |
handy | Nostalgist |
| PC Engine / TurboGrafx-16 | PC_ENGINE |
mednafen_pce_fast | Nostalgist |
| WonderSwan / Color | WONDERSWAN, WONDERSWAN_COLOR |
mednafen_wswan | Nostalgist |
| Virtual Boy | VIRTUAL_BOY |
mednafen_vb | Nostalgist |
| Neo Geo Pocket / Color | NEOGEO_POCKET, NEOGEO_POCKET_COLOR |
mednafen_ngp | Nostalgist |
| Commodore 64 | C64 |
vice_x64 | Nostalgist |
Note: Systems marked BinBashBanana use cores from BinBashBanana/webretro via jsDelivr. Dreamcast and PSP are currently unavailable due to lack of compatible WASM cores.
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
- Quick Start â Get up and running
- Usage Guide â Cloud saves, BIOS, RA integration
- API Reference â Complete props documentation
- Advanced Guide â Shaders, recording, controls, i18n
- Systems List â Per-console configuration
License
MIT Š Mudit Juneja
