Journal · 2026-05-12 · 7 min

Why we hand-code Canvas games.

Every game on Orvyn Living is built in plain HTML5 Canvas with vanilla JavaScript. No Phaser. No PixiJS. No Unity WebGL. No Construct. No asset packs. No build step. The whole studio is one folder of .js and .html files you can read top to bottom.

People ask why, sometimes politely and sometimes not. The honest answer is a mix of taste and arithmetic. Here's what actually goes into that decision when you're shipping 15 small games for a browser portal.

The math on a 15-game portal

Each of our games is between 200 and 400 lines of JavaScript. The shared engine is another ~120 lines. Total game code, including HTML pages: under 6,000 lines. Total payload of the entire site (HTML, CSS, JS, fonts, images) is under 200 KB before gzip. A single game, including the engine, weighs about 12 KB.

Phaser 3, our nearest "obvious" alternative, ships at ~1.4 MB minified. That's 75 times the size of every Orvyn game combined. For 15 games that mostly need a canvas, an animation loop, an input system, and some shape drawing, it's a lot of framework you're never going to use.

What you actually need

A small browser game is — almost without exception — five things:

  • A canvas with a high-DPI-aware setup function.
  • A requestAnimationFrame loop with a delta-time argument.
  • A unified input system that handles mouse, touch, and keyboard.
  • A way to play short, soft tones (Web Audio).
  • A few math utilities — clamp, lerp, rand.

Our shared engine.js is exactly that, and nothing else. It's about 120 lines. It loads in 1ms. It has zero abstractions for "scene managers" or "entity systems" or "asset pipelines" — because we don't have any of those things either, and we don't need them.

What you give up

To be honest about the trade-off: hand-coding means you give up a lot.

  • Physics. No Box2D under the hood. We wrote our own collision and trajectory math, which works for arcs and circle-circle collisions but won't scale to a platformer with sloped surfaces.
  • Tilemaps. No Tiled importer, no chunk-streaming. Snake Garden is a 24×16 grid with hand-rolled cell math. Larger worlds would mean writing all of that.
  • Sprite atlases. All visuals are drawn live with shapes, gradients, and the occasional inline SVG. There are no PNGs to load, no atlases to pack — but also no pixel art if you wanted it.
  • Multiplayer. No netcode glue. Single-player only.

Each of these would be hard or expensive to bolt on later. We accept that. None of our games would work better with a tilemap, and none of them would benefit from physics we'd have to wrestle to behave like our hand-rolled physics already does.

What you keep

Hand-coding gives you back three things that, for a small studio, matter more than features:

  • Load time. Every Orvyn game starts playing within ~200ms of clicking the link, on a phone, on cellular. That's the entire competitive moat for a browser-game portal. People don't wait for browser games. They go elsewhere.
  • Debuggability. When something's wrong, the call stack is the whole codebase. There's no plugin, no version pin, no Stack Overflow thread for an undocumented engine quirk. You read the code that's running and fix it.
  • Longevity. Phaser 2 sites broke when Phaser 3 dropped. Phaser 3 sites will break when Phaser 4 drops. Our sites don't depend on anything that can drop. They depend on Canvas API and JS, both of which have been stable for over a decade and almost certainly will be for another decade.

When we'd switch

If we ever needed: tilemap-based level design at scale, a real physics simulation (cloth, ragdolls, multi-body), pixel-perfect sprite work, or networked multiplayer — we'd reach for Phaser or Pixi. We'd write the bigger game in the bigger tool and keep the small ones in the small tool. They don't have to all live in the same engine.

For now, the games we want to make are five-minute browser arcades, and a 12 KB file delivers them better than a 1.4 MB framework would. That's the whole argument.

For other small studios

If you're considering shipping a small browser game collection: try writing one in plain Canvas first. You'll know within a weekend whether your idea needs an engine. Most don't. The few that do, you'll feel.

Our shared engine is open in your browser right now (View Source on any game page). Steal anything useful.

← All notes Play a game