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

sideloadplay

v0.1.1

Published

The Sideload developer CLI: sign in with an invite token and publish a game.

Readme

sideloadplay

The developer CLI for Sideload. Validate a game, preview its listing, test it in the Launcher, and publish it.

Validation and local testing work without an account or invite token. Publishing requires an invite token. Sideload is in developer alpha with no self-service sign-up; tokens are issued by the operator.

Running it

Nothing to install:

npx sideloadplay --help

Node 22 or newer.

If you would rather have it on your path, npm install -g sideloadplay gives you both sideloadplay and the shorter sideload.

Validating

npx sideloadplay validate <dir>

validate runs every check publish runs against <dir> — the same sideload.json, the same artwork — with no token, no network, and no upload. There is nothing to sign in for: it works before you have an invite token, and its verdict is exactly the one publish will reach for the same directory.

Signing in

npx sideloadplay login

login reads your invite token from standard input, and there is no flag and no environment variable that will pass it instead. That is deliberate: a flag ends up in your shell history and in CI logs, and standard input does not. Paste the token when prompted, or pipe it:

npx -y sideloadplay login < token.txt

-y matters when you pipe: without it, npx may ask to confirm the install and read the answer from the same standard input your token is on.

The token is verified against the API and stored in your operating system's keychain. Where there is no keychain, it is written to a file only you can read. A token that does not match a developer is reported and stored nowhere.

Running it in the launcher

Preview a prepared build's listing before playing:

npx sideloadplay dev <dir> --listing

This opens a read-only preview of its Markdown description, creator credits and artwork. Choose Play to test the game. To launch gameplay directly:

npx sideloadplay dev <dir>

Both modes run the same checks as validate, serve the prepared directory, and open the Sideload Launcher. They do not compile or publish the game and require no account or invite token. <dir> must contain the static build, sideload.json and its referenced files; the manifest's entry_file selects the game entry.

The build is served under /g/<localGameId>/dev/, matching the nested path shape of a published build (/g/<gameId>/<buildId>/). Root-absolute asset paths such as /assets/thing.glb can therefore fail here just as they would after publishing. Use paths relative to the entry HTML or module instead.

Local launch currently requires macOS and a compatible installed Sideload Launcher. Keep the command running while previewing or playing; Ctrl-C or SIGTERM stops its local server. JSON mode reports validation, port conflicts, opener failures, and launcher rejection or compatibility timeouts.

The launcher also offers Settings → Run a local game: select the prepared folder, review its listing, then Play. Recent folders can be reopened using the controller; the native folder picker uses the operating system's keyboard/mouse interaction.

CLI and Settings use the same canonical folder identity and persisted loopback port, so returning to the same folder preserves its save origin through rebuilds. Separate folders have separate saves even if their manifests use the same slug. Moving a folder creates a new identity; old random-port development saves are not automatically migrated. Assignments live in ~/Library/Application Support/Sideload/local-builds.json; forgetting a recent folder does not delete its assignment or saves.

If its assigned port is occupied, stop the other CLI/launcher local session and retry. Sideload never silently changes the port. A compatible updated launcher is required to acknowledge the new handoff. Older --dev-url launcher callers remain a legacy game-only path. Both local entry points enforce the hosted-game network policy: requires.network: true alone does not grant arbitrary network access.

Publishing

npx sideloadplay publish <dir>

<dir> holds your built game, a sideload.json describing it, and your store artwork. The build must be servable as static files with an entry point — index.html unless sideload.json says otherwise.

Everything is validated locally first, and nothing is uploaded until it all passes. Then the build and artwork upload, and your listing is created or updated.

A candidate with a cover and at least three screenshots is submitted for review. Without them the candidate stays a draft, and the output names what is missing. Publishing again uploads a new build; earlier builds are never modified.

The command reports candidate review status separately from live availability. When the API supplies them, JSON and prose include the game ID, candidate build ID, live build ID and live status. Older servers may omit these additive fields; the CLI reports live availability as unknown rather than guessing that an update is live or remains live.

Uploading submits a candidate for review. An existing approved version remains live until the operator approves the update. Keep the returned game and build IDs to coordinate review with the operator.

sideload.json

{
  "$schema": "https://sideloadplay.com/schema/sideload.schema.json",
  "slug": "your-game",
  "title": "Your Game",
  "short_description": "One line, at most 140 characters.",
  "description": "./DESCRIPTION.md",
  "version": "1.0.0",
  "entry_file": "index.html",
  "engine": "threejs",
  "renderer": "webgl2",
  "tags": ["Racing"],
  "input": ["keyboard", "mouse", "gamepad"],
  "controller_support": "full",
  "lifecycle": "unmanaged",
  "estimated_playtime_min": 90,
  "languages": ["en"],
  "content_rating": "everyone",
  "developer": { "name": "Your Studio" },
  "requires": {
    "pointer_lock": true,
    "fullscreen": true,
    "network": false,
    "shared_array_buffer": false
  },
  "size": { "initial_load_mb": 8, "total_mb": 24 },
  "assets": {
    "cover": "./store-assets/cover.png",
    "screenshots": ["./store-assets/1.png", "./store-assets/2.png", "./store-assets/3.png"]
  }
}

The $schema line gives you completion and validation in any editor that understands JSON Schema, including the list of tags you can use.

description may be markdown inline, or a path to a .md file — a 4,000-character description is not something to hand-edit inside a JSON string.

developer credits the game's creator; it does not set the listing's owner. The authenticated account supplies the publisher identity. Use a nonempty developer.name and, when available, these optional HTTP(S) links:

  • website_url: the creator's website.
  • source_url: the repository for the version you ship.
  • upstream_url: the original repository when your version is an adaptation.

Preserve original creator credits and license notices. Changing creator metadata does not transfer publishing ownership. The Launcher labels a distinct publisher separately; local previews do not invent publisher information.

requires.network must be honest. Declaring false and then making network requests at runtime breaks the developer agreement.

Artwork

Cover, Hero and Screenshots must be exactly 1920×1080 (16:9), so a gameplay screenshot at those dimensions is a valid cover. Logo has separate bounds.

| Asset | Size | Required | |---|---|---| | Cover | 1920×1080 | yes | | Screenshots | 1920×1080, gameplay only | 3 to 8 | | Hero | 1920×1080 | optional | | Logo | transparent PNG within 1200×400 | optional |

Each artwork file is capped at 5 MB. Cover, Hero and Screenshots use PNG or JPEG; Logo uses transparent PNG.

--json

Every command takes --json. Failures are reported as structured objects rather than prose, so a script or an agent can act on them:

{ "id": "screenshot_dimensions", "actual": "1920x1200", "expected": "1920x1080" }

License

MIT.