macemu

Classic Mac software, running in your browser tab

How a 1991 Macintosh Boots in a Browser Tab in Two Seconds

September 2026 · Andrew Nakas

A Macintosh Quadra 650 with System 7.5.3 and a two-hundred-megabyte hard disk starts on this site in about two seconds. Nothing is installed and nothing is downloaded in advance. This is how.

The emulators are old, and that is the point

None of the emulation here is new work. Mini vMac has been emulating compact Macintoshes since 2001. Basilisk II and SheepShaver go back to the late 1990s. All three are mature C and C++ codebases that have been correct for a very long time, and all three compile to WebAssembly with Emscripten.

The packaging — getting them to run well in a browser, with a disk layer, sound, and input that behaves — is the work of Mihai Parparita's Infinite Mac, which is Apache-licensed and which this site builds on directly. If you find macemu useful, donate to that project. It is the layer everything here stands on.

The disk is the interesting part

The naive way to put an emulated hard disk on the web is to download the image. A System 7.5.3 disk with a useful amount of software on it is a couple of hundred megabytes, so that is a minute of waiting before anything appears — which is the difference between a thing people use and a thing people bounce off.

Instead the image is split into 256 KB chunks, each named after the hash of its own contents, with a small JSON manifest listing the chunks in order. The emulator asks for a sector; the disk layer works out which chunk holds it and fetches that one. Booting a Mac touches a few megabytes at most — the system file, the Finder, the extensions it actually loads — so a boot is a few dozen small requests, in parallel, from a CDN edge.

Naming a chunk after its contents has a second effect that matters more than the first. Every title on this site is a variant of the same base system disk: the same System Folder, the same fonts, the same StuffIt Expander, plus one application. Identical chunks have identical names, so they are stored once and cached once. Adding a game costs the storage of the game, not of a whole Macintosh. And because a name always means the same bytes, every chunk can be cached immutably for a year.

Cross-origin isolation, and the page split it forces

The emulator runs in a Web Worker and is dramatically faster when it can share memory with the main thread through a SharedArrayBuffer. Browsers only hand that out to a document that is cross-origin isolated: it must send Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp.

Those headers have a cost. require-corp blocks every cross-origin subresource that has not explicitly opted in — including every advertising iframe, and most third-party embeds. So a page cannot be both maximally fast and freely composable. It has to choose.

macemu chooses twice. The /run/ page is the article: history, controls, licensing, screenshots, the thing a search engine indexes. The /play/ page is the machine: isolated, no ads, no article, noindex, canonical pointing back at /run/. And /embed/ is the opposite extreme — framable by anyone, deliberately not isolated, running the slower fallback path, with a link back to the fast page.

This is not a hypothetical concern. On exebrowser.com, this site's DOS and Windows sibling, a site-wide COEP header meant that an advertising reviewer loaded the site and saw no advertisements at all, because the iframes were being blocked before they could render. That contributed to three rejections. One header, applied one level too broadly.

There is no build system

The site is static files on Cloudflare Pages. The generators are plain Node ESM scripts with no dependencies — node scripts/gen-pages.mjs reads a JSON catalogue and writes HTML. There is no framework, no bundler for the site itself, and no node_modules directory in the repository.

What there is instead is a gate. scripts/check-consistency.mjs runs before every deploy and refuses if anything has drifted: a title claiming to be playable with no disk manifest behind it, a screenshot declared but missing, a broken internal link, an advertising tag on an isolated page, a /play/ route without noindex, a sitemap listing a page that does not exist. Every one of those checks exists because the corresponding mistake is invisible from the outside until a visitor hits it.

What it still cannot do

No printing. No network inside the emulated machine. Getting files back out is not wired up. Mac OS X is a different architecture and a different problem, and is not attempted here. The what runs page is honest about all of it.

More