
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
A Game Boy emulator in TypeScript, designed for the browser and serverless environments.
The emulator runs headlessly with no DOM or Canvas dependency. Frames render to a raw Uint8Array RGBA buffer that can be encoded to PNG/JPEG or rendered to a terminal.
# Install
bun install
# Run tests
bun test
# Debug a ROM in the terminal
bun run debug path/to/rom.gb --watch
| Example | Path | Description |
|---|---|---|
| Vite Browser | examples/vite-browser/ | Client-side emulation via Web Worker + bidc |
| Next.js | examples/nextjs/ | Server-side emulation with App Router API routes |
| Screenshot | examples/screenshot.ts | CLI tool to capture a PNG from any ROM |
Run the browser demo (Vite + Web Worker):
# From repo root:
bun install
bun --cwd examples/vite-browser install
# Start demo:
bun run demo:browser
Then open the printed local URL, load a .gb/.gbc ROM, and use keyboard controls:
Z / X: A / BEnter / Backspace: Start / SelectThe browser worker protocol is powered by bidc.
A full Next.js App Router example with server-side emulation and a Game Boy UI. Stores data in memory; move to e.g. Redis for statefulness.
# From repo root:
bun install
bun --cwd examples/nextjs install
# Place a ROM in the example directory:
cp path/to/rom.gb examples/nextjs/rom.gb
# Start the dev server:
bun run demo:nextjs
The app exposes four API routes:
| Route | Method | Description |
|---|---|---|
/api/frame | GET | Returns the current frame as PNG (?advance=N) |
/api/input | POST | Sends a button press, returns the resulting frame |
/api/reset | POST | Resets the game, returns the first frame |
/api/state | GET | Returns game info (title, ROM size, frame count) |
Controls are the same as the browser demo (arrows, Z/X, Enter, Backspace, Space).
bun run debug <rom-path> [options]
| Flag | Default | Description |
|---|---|---|
--format <fmt> | green-half | Render format (see below) |
--width <n> | 80 | Output width in characters |
--frames <n> | 300 | Frames to run (batch mode) |
--interval <n> | - | Print every N frames (batch mode) |
--press <btn> | - | Press button at midpoint (batch mode) |
--stats | off | Show framebuffer stats |
--watch | off | Interactive mode |
| Format | Description |
|---|---|
green-half | Truecolor DMG green palette + half-block chars (highest quality) |
green | Truecolor DMG green, 1 char per pixel |
ansi-half | 256-color grayscale + half-blocks |
ansi | 256-color grayscale backgrounds |
ascii | Punctuation shading: .:-=+*#%@ |
blocks | Unicode blocks: ░▓█ |
half-blocks | Unicode half-blocks (no color) |
| Key | Action |
|---|---|
| Arrow keys | D-pad |
Z | A button |
X | B button |
Enter | Start |
Backspace | Select |
Space | Pause / Resume |
] or F | Speed up (1x / 2x / 4x / 8x / 16x) |
[ or D | Slow down |
1-5 | Set speed directly |
S | Step one frame (while paused) |
I | Toggle stats overlay |
R | Reset emulator |
Q / Ctrl+C | Quit |
import { Emulator, Button } from "./src/emulator";
// Load ROM
const rom = new Uint8Array(await Bun.file("pokemon.gb").arrayBuffer());
const emu = new Emulator(rom);
// Run frames
emu.runFrames(60);
// Handle input
emu.pressButton(Button.A);
emu.runFrames(5);
emu.releaseButton(Button.A);
// Get framebuffer (160x144 RGBA)
const fb = emu.getFramebuffer(); // Uint8Array, 92160 bytes
// Save state (excludes ROM data)
const state = emu.serialize();
await Bun.write("save.state", state);
// Restore state
const saved = new Uint8Array(await Bun.file("save.state").arrayBuffer());
const emu2 = Emulator.deserialize(rom, saved);
emu2.runFrames(1); // continues where it left off
Use the browser-safe entrypoint when bundling for the browser:
import { BrowserEmulatorClient, Button } from "gboy-ts/browser";
gboy-ts/browser excludes Node-only exports like PNG encoding.
State serialization is designed for frequent save/load in serverless:
bun test
bun test --watch # Watch mode
bun test src/__tests__/cpu-alu.test.ts # Run specific test file
FAQs
A headless Game Boy (DMG) emulator in TypeScript, built for serverless
We found that gboy-ts demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.