Originally published on the Sorceress blog . TL;DR: an HTML5 game is four things — an index.html host page, a JS module that owns the loop, a folder of sprites and audio, and a static zip anyone can open in a tab. What people actually mean Three deliverables share one core: A plugin-free canvas arcade — HTML/CSS/JS drawing to a , shipped as a static folder. A mobile HTML5 game — same bundle plus a viewport meta tag and a web app manifest. An itch.io HTML export — a zip whose root contains index.html . All three need a canvas, a requestAnimationFrame tick, relative asset paths, and zero installer. The loop in one minute Read input — drain a keys object that keydown / keyup listeners keep updated; mirror pointer events for mobile. Update — advance each object by velocity x dt (seconds since last frame), apply gravity, resolve collisions. Draw — ctx.clearRect(0, 0, W, H) , then one ctx.drawImage per sprite. Start audio on the first user gesture so autoplay policy stays happy. About thirty lines, zero dependencies. The discipline that keeps it honest Draw never mutates state; update never touches the DOM. Keep a plain state object, a keys map, and a ctx reference. Update reads keys and mutates state; draw reads state and paints. One trap: size the canvas with its width / height attributes , not CSS alone, or the bitmap stretches and smears. Why it is still the best first-game target Distribution is a URL or a zip: no store review, no signing certificate. Canvas, Web Audio and localStorage are stable across browsers, and itch.io, GitHub Pages and Netlify serve static folders free. Full guide: sorceress.games

How to Make an HTML5 Game (Browser Loop, 2026)
Sorceress

