npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

browser-port

v0.2.0

Published

Give your agent the power to port any open-source desktop app or game to the browser, so it runs from a link anyone can open.

Readme

browser-port

Turn an open-source C/C++ SDL or raylib game into a link anyone can play, in one command, or get an honest reason why not.

CI License: MIT Node 20+ MCP server

A C + SDL2 Tetris clone, built to WebAssembly by browser-port and played in headless Chrome during verify.

Play them in your browser: Pong · Snake · Space shooter · SDL Tetris · all demos

Try it · Use it with your agent · Real ports · How it works · Limits


Found a great open-source C or C++ game that only runs on someone's desktop? Point browser-port at the repo. It checks whether the code can run in a browser, works out the sources, libraries, and assets on its own, compiles to WebAssembly with Emscripten, reads and fixes common build failures, packages a static site, then opens it in a real browser and proves it works. You get a folder you can put on any static host, a measured frame rate, and a report of everything that was done and checked, or an honest "not supported yet" with the blocker named.

Try it

npm install -g browser-port        # or run it with npx browser-port ...
brew install emscripten            # or have Docker running for the emscripten/emsdk image
npx playwright install chromium    # the browser `verify` uses

Then port a game in one command:

browser-port port https://github.com/ryanpcmcquen/basque

It inspects, derives the sources and libraries, builds (retrying with known fixes if the first build fails), packages, verifies in headless Chrome, and prints a link you can open and play. On a fresh run (Apple M4, Emscripten 6.0.12) it reported:

  build attempt 1: source/basque.c  [asyncify=off]
  build ok; package + verify
  verified at 50.1 fps

Playable.
Verified in headless Chrome at 50.1 fps.
Play it at: http://127.0.0.1:52231/

If it cannot be ported, you get the reason instead:

$ browser-port port https://github.com/some/qt-app
Not supported yet: Uses the Qt toolkit. Qt draws through its own native windowing and has no
Emscripten port in this tool. Not supported yet.

The individual steps (inspect, build, package, verify, report) are still there for when you want to hand-edit the source between them.

Use it with your agent

browser-port setup          # shows what it would change
browser-port setup --yes    # registers the MCP server with Claude Code, Codex and Cursor

Then just ask:

"Port github.com/ryanpcmcquen/basque to the browser and prove it works."

The agent follows skills/browser-port/SKILL.md: it calls the one port operation, reads the measured result, serves the link, and says plainly when something isn't supported. It drops to the individual steps only when the source needs a hand edit.

setup registers npx -y browser-port mcp, which works once the package is on npm. Until then, point your agent at the local build instead: claude mcp add browser-port -- browser-port mcp.

Real ports

Every row was produced end to end on a Mac with browser-port. Each folder in examples/ has the evidence bundle, screenshots, and the runnable site with the upstream license.

| Program | What it is | Result | | --- | --- | --- | | packt-shmup | C++ shoot-em-up, SDL2 + SDL2_image | port in one command: 60 fps. First build linked only main.cpp and failed; it recompiled all seven sources and linked | | basque | C top-down 2D engine, SDL2 + image/mixer/ttf | port in one command: 50.1 fps, no manual flags | | saanp-snake | C snake, SDL2 + SDL2_ttf, blocking loop | port in one command: made playable by a build-time yield shim (no source edit) | | pong | C++ Pong, SDL2 + SDL2_ttf, blocking loop | port in one command: made playable by the yield shim; its vendored SDL2 copy was ignored | | sdl-tetris | C game, SDL2 + SDL2_ttf | Plays in the browser, about 55 to 57 fps, no console errors | | brainheck | C terminal program (stdin/stdout) | Browser output matched the native build for the same inputs | | hexyl | Rust hex viewer | "Not supported yet", with the reason |

Honest notes on the limits of one command: it ports games whose loop is web-ready (emscripten_set_main_loop), yields through SDL_Delay under ASYNCIFY, or runs a plain blocking while loop that it makes yield with a build-time shim (ASYNCIFY plus wasm-ld --wrap on the SDL present and poll calls, so each frame and each idle poll returns control to the browser; no source edit). What one command still cannot do: programs that fail to compile upstream, that need a codec Emscripten does not ship (for example FLAC in SDL2_mixer), or that trap at runtime are reported with the reason, not papered over. A loop that neither presents nor polls events each iteration has no point to yield at and would still need a hand edit.

How it works

flowchart LR
  A[GitHub repo] --> B[inspect]
  B --> C[build<br/>Emscripten]
  C --> D[package<br/>static site]
  D --> E[verify<br/>headless Chrome]
  E --> F[report<br/>evidence bundle]

| Step | What it does | Tools it drives | | --- | --- | --- | | port | The whole pipeline in one call: inspect, derive sources/libraries/assets, build with a bounded auto-fix retry ladder, package, verify, print a link with the fps. Falls back to an honest not-supported | all of the below | | inspect | Language, build system, libraries, assets, entry point, and a verdict: likely, needs changes (each blocker with its usual fix), or not supported (Qt, GTK, native windowing, threads, sockets) | git | | toolchain | Finds a local emcc, else the emscripten/emsdk Docker image, else tells you how to install it | Emscripten, Docker | | build | Compiles with the right flags (-sUSE_SDL=2, asset preloading, memory growth, ASYNCIFY when needed) and records every command | emcc | | package | A self-contained site: canvas or terminal page, loading progress, fullscreen, keyboard focus, an error panel | | | serve | Local preview with the correct wasm MIME type (--coi adds the headers threads need) | | | verify | Console errors, non-blank frames, fps, scripted key presses, screenshots; for terminal programs, browser output vs a native build | Playwright, Chromium | | report | Markdown and JSON: repo and commit, toolchain versions, commands, source patch, results, limits | |

Every step is a CLI subcommand (add --json) and an MCP tool.

What it can't do

  • Only C and C++ programs that use SDL2, raylib, or plain stdin/stdout. Other languages and toolkits (Qt, GTK, wxWidgets), native X11/GLX/WGL/Cocoa windowing, the Win32 GUI, raw sockets, and threads get an honest "not supported yet" with the reason. OpenGL used through SDL2 or raylib is fine.
  • One command auto-fixes build failures (missing SDL port libraries, uncompiled sources, a missing <emscripten.h>, implicit-declaration errors, a small stack) and makes a blocking loop yield with a build-time shim (ASYNCIFY plus wasm-ld --wrap on the SDL present and poll calls), without rewriting source. A loop that neither presents a frame nor polls events each iteration has no yield point and still needs a hand edit to emscripten_set_main_loop.
  • Codecs Emscripten does not bundle (for example FLAC in SDL2_mixer) are not available.
  • A program that reads all of stdin as its input can't also take interactive input in the terminal page.

Privacy and safety

Everything runs on your machine. The only network traffic is cloning the repo you ask for and, on the Docker path, pulling the emscripten/emsdk image. It never calls an LLM and sends no telemetry. setup only touches the three agent config files above, backs them up first, and is a dry run unless you pass --yes.

License

MIT, Copyright (c) 2026 Abel Yagubyan. Ported programs keep their own licenses; package --license copies the upstream license into the site.