Skip to content

Quick start

1. Get the SDK

Clone or download this repository, then copy packages/js/src/apiexpose-sdk.js next to your page (keep apiexpose-sdk.d.ts too if you use TypeScript tooling). There is nothing to build.

2. Minimal page

<!DOCTYPE html>
<html>
<body>
  <h1 id="game"></h1>
  <script type="module">
    import { APIExposeClient } from './apiexpose-sdk.js';

    const client = new APIExposeClient(); // defaults to 127.0.0.1:12345

    async function refresh() {
      let game = null;
      try { game = await client.getCurrentGame(); } catch { /* nothing selected yet */ }
      document.getElementById('game').textContent = game?.name ?? 'no game';
    }

    client.on('game.changed', refresh);          // fires on ES selection and launch
    client.on('connection.restored', refresh);   // fires on (re)connect
    refresh();
    client.connect();
  </script>
</body>
</html>

Open the file in a browser on the RetroBat machine: the title follows the game selected in EmulationStation.

Render first, connect second

Call your first REST refresh before (or independently of) connect(). REST answers immediately; the WebSocket then keeps you updated. connect() never throws and keeps retrying in the background.

3. Options

const client = new APIExposeClient({
  host: '127.0.0.1',
  port: 12345,          // APIExpose REST + WebSocket
  streams: null,        // null = single /ws firehose; or ['score','timer','frontend']
  autoReconnect: true,
  reconnectDelayMs: 1000,
  maxReconnectDelayMs: 15000,
  log: (level, msg) => console.log(level, msg) // silent by default
});

4. Subscribing to events

// normalized aliases
client.on('game.changed', (e) => { /* selection or launch */ });
client.on('score.changed', (e) => console.log(e.payload));
client.on('achievement.unlocked', (e) => { /* 🏆 */ });

// raw types and wildcards
client.on('retroachievements.*', (e) => console.log(e.rawType));
const off = client.on('*', (e) => console.log(e.rawType, e.payload));
off(); // every on() returns its unsubscribe function

See Events for the full list.

5. Try the samples

The three samples in samples/html run as plain files in any browser:

  • now-playing-basic — game name, system and artwork card.
  • score-basic — live score + timer HUD.
  • event-debug-monitor — every event in real time, with a capabilities report.