obOB STUDIO
Dev Log

Why I Build Everything in the Browser

5 min read

Someone sent me a link and I was playing in 3 seconds

That's the pitch. That's the whole argument for building games in the browser.

No "Download on the App Store." No "Requires Windows 10 or later." No Steam client update. No 2GB install. Someone shares a URL, you tap it, and you're in. Playing. Right now. On whatever device you have in your hand.

I've shipped 14 projects now and every single one runs in a browser. It's not a compromise — it's a deliberate choice, and I'm more convinced of it with every project.

The universal platform

Every phone has a browser. Every tablet. Every laptop. Every desktop. Every Chromebook in every school. Every smart TV with a crummy built-in browser that still renders HTML. The browser is the closest thing we have to a universal runtime.

When I ship a Godot game as a web export, it runs on my friend's iPhone, my dad's Android tablet, my own Windows laptop, and a Linux machine I've never touched. I didn't write platform-specific code. I didn't sign any developer agreements. I didn't pay Apple $99/year for the privilege of distributing my software.

That matters to me. Not just because I'm cheap (I am), but because I genuinely believe software should be accessible. If someone wants to play my game, the barrier should be zero.

WebGL2 is surprisingly capable

People hear "browser game" and think Flash-era stick figure animations. But WebGL2 is a real GPU API. It's OpenGL ES 3.0 in a browser tab. You can do physically-based rendering, shadow maps, post-processing, instanced drawing — real graphics.

Godot 4's Compatibility renderer targets WebGL2 and the results are impressive. Oliver's Racers runs with dynamic lighting, procedurally generated terrain, particle effects, and real-time shadows — all in a browser at 60 FPS on a mid-range phone.

No, you're not going to match Unreal Engine 5 Nanite in a browser. But for the kinds of games I build — arcade racers, flight sims, hide-and-seek — WebGL2 is more than enough.

PWA: feeling native without the app store

Progressive Web Apps bridge the gap between "it's a website" and "it feels like an app." Add a manifest.json, a service worker, and the right meta tags, and your browser game can:

  • Install to the home screen with its own icon
  • Launch in fullscreen without the browser chrome
  • Work offline (if you cache the right assets)
  • Show a splash screen on launch

Oliver's Racers and Oliver's Planes are both PWAs. When you install them, they look and feel exactly like native apps. No address bar, no tabs — just the game, fullscreen. Players have told me they didn't realize it was a browser game until I mentioned it.

// Service worker: cache game assets for offline play
self.addEventListener("install", (event) => {
  event.waitUntil(
    caches.open("game-v1").then((cache) =>
      cache.addAll([
        "/games/olivers-racers/index.html",
        "/games/olivers-racers/index.js",
        "/games/olivers-racers/index.wasm",
        "/games/olivers-racers/index.pck",
      ])
    )
  );
});

self.addEventListener("fetch", (event) => {
  event.respondWith(
    caches.match(event.request).then((r) => r || fetch(event.request))
  );
});

The elephant in the room: WASM file sizes

Okay, I have to be honest about the downside. Godot's web export compiles the entire engine to WebAssembly. The .wasm file for Oliver's Racers is about 39 MB. That's... big. On a slow connection, the initial load takes a while.

But here's the thing: service workers fix repeat loads completely. The first visit downloads 39 MB. Every visit after that loads from cache in under a second. And with a loading screen that shows progress, even the first load feels manageable.

I've also started gzipping the WASM files on CloudFront. A 39 MB .wasm compresses to about 11 MB with gzip. That's still not tiny, but it's in the range of "acceptable for a full 3D game." People regularly download 100+ MB mobile games from the App Store without blinking.

Godot's web export is production-quality

I want to give Godot a specific shout-out here. Their web export is not a second-class citizen — it's a first-class build target. The export process generates an index.html, a .js loader, a .wasm binary, and a .pck asset pack. Drop those files on any web server and you have a running game.

Audio works. Touch input works. Gamepad works. Fullscreen works. The thread model (single-threaded for maximum compatibility) is sensible. I've shipped three Godot games to the web and the only real gotcha was cross-origin isolation headers for SharedArrayBuffer (which you only need for multi-threaded mode, which I don't use).

Sharing is the killer feature

All the technical arguments aside, the real reason I build for the browser comes down to one thing: sharing.

When I finish a game, I post a link. Not a build artifact. Not a zip file. Not "available on Steam, add to wishlist." A URL. You click it and you're playing. You can text it to a friend. You can post it on Twitter. You can embed it in an iframe on another website.

This frictionless sharing is why the web won in the first place. It's why blogs beat desktop publishing. It's why YouTube beat DVDs. The best distribution channel is no distribution channel — just a link.

Every project I build reinforces this. When someone plays my game 3 seconds after I send them a link, I know I made the right platform choice.

ob

Written by Oliver

Indie game developer building 3D web experiences in Godot and Next.js. I write about creative coding, procedural generation, and game feel.