Installation

Get up and running in under 5 minutes.

1. Install the Package

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

2. Configure Security Headers

⚠️ Required for Performance

The emulator uses SharedArrayBuffer for high-performance audio and video threading. Modern browsers require specific security headers to enable this feature.

Next.js (next.config.js)

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

module.exports = nextConfig;

Vercel (vercel.json)

vercel.json
{
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        { "key": "Cross-Origin-Opener-Policy", "value": "same-origin" },
        { "key": "Cross-Origin-Embedder-Policy", "value": "require-corp" }
      ]
    }
  ]
}

Cloudflare Pages (_headers)

public/_headers
/*
  Cross-Origin-Opener-Policy: same-origin
  Cross-Origin-Embedder-Policy: require-corp

Nginx

nginx.conf
location / {
    add_header Cross-Origin-Opener-Policy "same-origin";
    add_header Cross-Origin-Embedder-Policy "require-corp";
}

3. External Resource Considerations

With COEP enabled, all external resources (ROMs, BIOS) must be served withCross-Origin-Resource-Policy: cross-originOR use crossorigin="anonymous".

Recommended Setup

  • Host ROMs on the same domain as your app
  • Use a CDN that supports CORP headers (Cloudflare R2, AWS S3)
  • Generate presigned URLs for private ROM storage
  • Don't hotlink ROMs from external sites without CORP headers

4. Verify Setup

Open your browser's DevTools console and check for:

Console Check
// Should return true
console.log('SharedArrayBuffer available:', typeof SharedArrayBuffer !== 'undefined');

// Should return true
console.log('crossOriginIsolated:', window.crossOriginIsolated);

Both should be true. If crossOriginIsolated is false, your headers are not configured correctly.