How HTML5 Ninja Games Work in a Browser

Open a browser game and a surprising amount happens in the first hundred milliseconds. This guide walks through the canvas, the frame loop, input handling, audio and local storage — the five parts every HTML5 game is built from.

There is no plugin, no installer and no download. You click a link and a game is running. Here is what actually happens, in the order it happens, using the games on this site as the worked example.

Step 1: the page loads, and it is tiny

An HTML5 game page is an ordinary web page. It ships HTML, a stylesheet and some JavaScript. A game like Ninja Dash is a few kilobytes of script on top of a shared engine — smaller than most photographs on the web.

That size is why it starts instantly. There are no art assets to download because everything is drawn with code, and no audio files because the sounds are synthesised in the browser.

Step 2: the canvas

The play area is a single HTML element:

<canvas width="960" height="540"></canvas>

A canvas is a rectangle of pixels the page can draw into. JavaScript asks it for a drawing context and then issues drawing commands — fill this rectangle, stroke this arc, draw this path.

Crucially, the canvas has no memory of what it drew. There are no objects on it, no elements to inspect, nothing to click. It is a single image. Everything a game shows must be redrawn from scratch every frame, which is exactly what the loop below does.

This is also why game instructions must live outside the canvas. Nothing inside it is text as far as the browser is concerned, so a screen reader cannot read it. On this site the controls, rules and tips all live in ordinary HTML beneath the play area for that reason.

Internal resolution versus display size

The canvas element has two separate sizes: the internal resolution (its pixel buffer, 960×540 here) and the display size set by CSS. Game code works entirely in internal coordinates and the browser scales the result, which is why the same code runs correctly on a 360-pixel-wide phone and a 4K monitor without a single changed number.

High-density screens add one wrinkle: to look sharp, the pixel buffer should be multiplied by the device pixel ratio, then the drawing scaled to match. That is a handful of lines in the engine and the reason these games do not look blurry on a phone.

Step 3: the loop

Games are a loop that runs sixty times a second:

  1. Read input.
  2. Advance the simulation by one small time step.
  3. Clear the canvas and redraw everything.
  4. Wait for the next screen refresh.

Step 4 is handled by requestAnimationFrame, a browser function that calls your code just before the next repaint. Using it instead of a timer means the game runs in step with the display, pauses automatically in a background tab, and does not waste battery.

Why fixed timesteps matter

Screens refresh at different rates — 60Hz, 90Hz, 120Hz, 144Hz. If physics advanced by "however long the last frame took", the same jump would reach different heights on different monitors.

The fix is to decouple simulation from rendering. The engine accumulates elapsed time and runs the physics in fixed 1/60-second steps, however many are needed, then draws once:

accumulator += deltaTime;
while (accumulator >= STEP) {
  update(STEP);
  accumulator -= STEP;
}
render();

A cap on the loop count prevents a "spiral of death" where a slow frame requests more steps than the machine can run. In practice this means a 144Hz gaming monitor and a tired laptop simulate identical jumps — only the smoothness differs.

Step 4: input

The browser reports keydown, keyup, pointerdown, pointermove and pointerup. A game engine normalises all of them into a small set of actions — up, down, left, right — so the game logic never knows or cares whether a jump came from the space bar, an arrow key, a swipe or a tapped button.

Two details make the difference between a game that feels good and one that does not:

Edge versus level input. A jump should fire once on the press (an edge), while running left should continue for as long as the key is held (a level). Confusing the two produces either a character that jumps repeatedly or one that refuses to move.

Preventing the page from moving. Pressing space or swiping up would normally scroll the page. Games suppress that during play, and set touch-action: none on the play area so the browser does not steal gestures for scrolling and zooming.

Step 5: audio

The Web Audio API can generate sound mathematically — an oscillator at a frequency, an envelope that fades it in and out. The blips in these games are a few lines of code each rather than downloaded files:

osc.frequency.setValueAtTime(430, now);
osc.frequency.exponentialRampToValueAtTime(720, now + 0.11);

That is the jump sound: a short square wave sliding from 430Hz to 720Hz.

Browsers will not let audio start without a user gesture, which is why the audio context is created or resumed on the first click or key press rather than at load. It is also why a game sometimes seems silent until you interact with it.

Step 6: saving your score

localStorage is a small key-value store inside your browser, private to the site that wrote it, and it is where these games keep your best score, favourites and preferences.

The trade-offs are worth understanding:

  • Private. Nothing is uploaded. No server, not even ours, has a copy of your score.
  • Per browser. Chrome on your laptop and Safari on your phone keep separate scores.
  • Fragile. Clearing site data deletes them permanently, and private browsing windows discard them at the end of the session.
  • Blockable. Some privacy settings deny access entirely, so well-written games wrap every read and write in error handling and carry on without saving.

What this architecture is good and bad at

Good at: instant starts, tiny downloads, running on anything with a browser, sharing by link, and privacy — a game that stores nothing on a server cannot leak anything from one.

Bad at: heavy 3D, very large asset sets, and guaranteed performance. A browser game shares the machine with every other tab, so frame rate depends on what else is open. Why browser games stutter covers what to do about that.

Key takeaways

  • A browser game is an ordinary web page drawing into a canvas element sixty times a second.
  • The canvas is a flat image with no memory, so everything is redrawn every frame — and instructions must live outside it for accessibility.
  • requestAnimationFrame syncs drawing to the display; a fixed timestep keeps physics identical across refresh rates.
  • Input from keys, pointers and touch buttons is normalised into a few shared actions.
  • Sounds are synthesised with the Web Audio API and must wait for a user gesture.
  • High scores live in localStorage: private, per-browser, and deleted when you clear site data.

Frequently asked questions

Do HTML5 games need Flash or a plugin?

No. Flash has been gone for years, and HTML5 games use only what the browser already ships: the canvas element, JavaScript, and the Web Audio API.

Why do browser games sometimes run slowly?

Because they share the CPU and GPU with every other tab, extension and application. Closing other tabs, disabling heavy extensions and plugging in a laptop that is on battery-saver all help measurably.

Can I play HTML5 games offline?

Only if the game explicitly supports it with a service worker. The games on this site require the page to load, though they make no network requests once running.

Why is there no sound until I click?

Browsers block audio until the user interacts with the page, to stop sites playing sound automatically. The game creates or resumes its audio context on your first input.

Where exactly is my high score stored?

In your browser's localStorage for this domain — a file on your own device managed by the browser. It is never transmitted, which also means it cannot be recovered if you clear it.

Is playing browser games safe?

A static HTML5 game asks for no permissions, has no login and stores nothing on a server. The usual caution applies to the site around it rather than to the game technology itself.

References

Ready to put this into practice?

Everything above is easier to feel than to read about. Open the game and try one run with just one of these ideas in mind.

Play Ninja Dash

Games covered in this guide

All games →