Skip to content

Repository files navigation

Runner 404

A drop-in endless-runner game for your 404 page. One script tag, zero config.

Think Chrome's offline dinosaur - except themed around the 404 you just hit. The "0" jumps over 404, 500, 503 and 418 obstacles. Spacebar or tap to jump. Persistent high score. Light/dark theme follows the user's system preference.

Quickstart

Pick the path that matches your stack.

1. Plain HTML (no build step)

<div data-404-runner></div>
<script src="https://cdn.jsdelivr.net/npm/runner-404"></script>

That's it. The script finds every element with data-404-runner and mounts the game inside.

2. Web component

<script src="https://cdn.jsdelivr.net/npm/runner-404"></script>
<runner-404 theme="auto"></runner-404>

3. NPM / bundler

npm install runner-404
import { mount } from 'runner-404';

const game = mount('#game-container', { theme: 'dark' });
// later, if you need to:
game.destroy();

Options

All three embed paths accept the same options. Names differ between paths:

Option <div data-404-runner> attribute <runner-404> attribute mount() option
Theme data-theme="auto" theme="auto" theme
Width (px) data-width="600" width="600" width
Height (px) data-height="200" height="200" height
Auto-start data-autostart autostart autoStart
Tap anywhere data-tap-anywhere="false" tap-anywhere="false" tapAnywhere

theme accepts 'light', 'dark', or 'auto' (follows prefers-color-scheme, default).

tapAnywhere defaults to true: any tap on the page jumps, except on links, buttons, inputs, and other interactive elements. Set to false to constrain touch input to the game canvas only.

Programmatic API

const game = mount(target, options);
game.start();          // begin the loop
game.stop();           // pause the loop
game.reset();          // back to ready state
game.destroy();        // remove canvas, detach listeners
game.score;            // current score
game.highScore;        // persisted best

target can be a CSS selector string or an HTMLElement.

Controls

  • Tap Space / ↑ / W for a short hop (good for landing on platforms)
  • Hold the same keys for a full jump (good for clearing tall walls)
  • Tap / hold anywhere on the page on mobile - interactive elements (links, buttons, inputs) are excluded so they still work normally

Accessibility

  • Canvas is role="img" with a descriptive aria-label
  • Respects prefers-reduced-motion
  • Keyboard input is global once mounted — players don't have to click first

Browser support

Modern evergreen browsers (Chrome, Firefox, Safari, Edge). Uses canvas 2D, custom elements, and prefers-color-scheme. No polyfills needed for the supported targets.

Bundle size

Approximately 5 KB gzipped (IIFE build, minified). No runtime dependencies.

Contributing

npm install
npm run dev      # tsup watch mode
npm test         # vitest
npm run build    # produces dist/ (ESM + CJS + IIFE)

Open the demo/ HTML files after a build to play locally.

License

MIT

Releases

Contributors

Languages