Single HTML file games are playable pages with no install step: markup, styles, script and art in one document. Anything the page has to fetch from beside it is what breaks the format.

The appeal is portability. The cost is that a few categories of game cannot be built this way at all, and it is worth knowing which before you start.
The rule that defines single HTML file games
One file, zero neighbours. That means:
- Styles in a
<style>block, not in an external stylesheet. - Script in a
<script>block, not in a separate.jsfile. - Art drawn on canvas, or embedded as base64 data URIs.
- Level data written as a JavaScript object, not fetched as JSON.
The last one catches people out. A page opened from disk is not allowed to read files next to it, so fetch('levels.json') fails even though the file is right there. That restriction is the file protocol doing its job.
What fits and what does not
| Game feature | Fits in one file | Why |
|---|---|---|
| Canvas arcade loop | Yes | Drawing commands need no assets |
| Puzzle or word game | Yes | Word lists inline as an array |
| Turn based board game | Yes | State lives in memory |
| High score on this device | Yes | Local storage, per browser |
| Small sound effects | Yes | Short clips embed as data URIs |
| Background music | Awkward | File size, or hotlink to a full address |
| Shared leaderboard | No | Needs a server to hold scores |
| Multiplayer | No | Needs a connection between players |
| Accounts and cloud saves | No | Needs a backend |
If your idea is in the bottom three rows, a single file is the wrong container and no amount of embedding fixes it.
Saving progress within the limits
Local storage is the only persistence available, and it has a specific shape worth understanding before you rely on it.
It is keyed to one browser at one address. A player who switches from a laptop to a phone starts over. A player who clears site data starts over. Nobody else can see the value.
That is fine for a personal best or a level unlock. It is not a leaderboard, and presenting it as one produces complaints.
Session storage is the shorter option, cleared when the tab closes, which suits an in progress run you do not want persisted.
Keeping the file small

The whole file downloads before anything appears, so weight is felt as a blank screen.
Draw instead of embed. Rectangles, circles and paths cost bytes in the dozens. A sprite sheet costs bytes in the hundreds of thousands.
Prefer SVG to raster. SVG inside the HTML is text, compresses well, and scales to any screen without a second copy.
Generate sound rather than embedding it. Tones from the audio API cost nothing in file size and suit arcade effects.
Skip web fonts. A web font that fails leaves the game in a default face anyway, and the system stack is instant.
Sharing so people actually play
- Open it somewhere neutral. The HTML file opener has never seen your folder, so a forgotten asset path fails there immediately.
- Paste the complete HTML into a document. It renders as a page of its own and the scripts run.
- Create the share link. Share, then Share link, then Create link. It is unlisted unless you tick Public on the web.
- Send the link. One tap on a phone, no download, no install.

Sending the file itself is the route that fails. Mail gateways strip HTML attachments, and a phone puts the file in storage with nothing offering to run it.
Most people who open your link are on a phone, so keyboard only controls exclude them.
Add touch handlers next to the key handlers and map screen regions to the same actions. Include the viewport meta tag so the canvas is not rendered at desktop scale and shrunk.
Size the canvas in CSS and scale the drawing context, rather than fixing pixel dimensions that happen to suit your monitor.
Why one file is worth the constraint
Everything in the page is visible in one place, which makes a game easy to hand to someone, easy to fork, and easy to archive. There is no build to reproduce in two years.
It also means the game can be revised in place. Paste it into a document once, and correcting a typo in the instructions is a click on the text rather than a re-upload, with the address unchanged.
For the code side of this, see HTML game code. For the general packaging technique, see self-contained HTML files.
Testing, distributing and archiving
Three checks, in order, catch nearly everything.
- Open the file from a folder containing nothing else. Any asset it was silently relying on now fails visibly.
- Open the console and play a full round. Errors thrown in a rare branch do not appear on the title screen.
- Open it on a phone. Touch input and canvas scaling are where single file games most often disappoint.
A single file game is unusually easy to keep. There is no repository to clone and no build to reproduce.
Put the version and date in the title, so a file found in two years identifies itself. Keep each release as its own document rather than overwriting, if the versions matter to you.
For the playable copy people use, keep one address and revise the page behind it. Players bookmark the link, and a bookmark that keeps working is worth more than a versioned filename.
If you want others to build on it, the source is already in the page. Anyone can view source, copy the file and change it, which is the oldest distribution model the web has.