Classic Mac OS 9 · PowerPC G3 / G4

The modern web, on a 25-year-old Mac.

MacSurf is a real web browser for Classic Mac OS 9. Real CSS3. Real ES5 JavaScript. Real PNGs with alpha. Rendering live inside the 64 MB memory floor of a beige G3.

150+ CSS PROPS DUKTAPE ES5 CODEWARRIOR 8 CARBON · QUICKDRAW GPLv2
MacSurf rendering CSS radial gradients on Mac OS 9
FIRST
NETSURF
ON OS 9
REAL CSS3REAL ES5 JAVASCRIPT NATIVE HTTPSPNG ALPHA CSS GRIDOPEN TRANSPORT POWERPC G3 / G4QUICKDRAW PLOTTERS REAL CSS3REAL ES5 JAVASCRIPT NATIVE HTTPSPNG ALPHA CSS GRIDOPEN TRANSPORT POWERPC G3 / G4QUICKDRAW PLOTTERS
// why MacSurf exists

The web outgrew Classic Mac OS twenty years ago.

Modern HTTPS killed it for good around 2016. Today, an out-of-the-box G3 or G4 running OS 9 can barely reach a single live website.

MacSurf brings the real web back. Not a screenshot proxy. Not a remote terminal. A native browser, built with the tools that were on the platform — CodeWarrior, the Carbon API, QuickDraw, Open Transport — running real CSS3 layouts and real JavaScript.

As far as we can find, it is the first serious NetSurf port to Classic Mac OS, and the first browser shipped on Mac OS 9 with native CSS Grid, custom properties, and ES5 JavaScript.

Puffy, the MacSurf puffin mascot
ELÍN · THE MACSURF PUFFIN built with stubbornness for a
25-year-old operating system
// what's in the box

Three pieces. One working browser.

The Mac speaks plain HTTP. The proxy bridges out to the modern, encrypted web — or skip it entirely with native TLS.

browser/
C · C89 · CW8

The browser /browser

A NetSurf fork with a macos9 frontend — Carbon UI, QuickDraw plotters, Open Transport networking, and the Duktape JavaScript engine.

FETCH → PARSE → CASCADE → LAYOUT → PLOT

proxy/
GO · STDLIB ONLY

The proxy /proxy

A TLS-stripping HTTP proxy. The Mac sends plain HTTP, the proxy fetches over HTTPS and hands plain HTTP back. One binary, no config.

DEPLOY ON A VPS · OR RUN IT LOCALLY

macSSL
C · CW8 · SIBLING REPO

macSSL native TLS

A native TLS 1.2 library for OS 9 — modern HTTPS straight from the Mac, no proxy required. Built on BearSSL with ten embedded root CAs.

HTTPS · DIRECT FROM THE METAL

// what works today

A full rendering engine, not a demo.

Around 150 CSS properties consumed in layout, a complete ES5 engine, five image formats, and real cooperative-multitasking networking.

Rendering pipeline

  • Full NetSurf fetch → parse → cascade → layout → plot
  • Native libcss with var() resolution
  • QuickDraw plotters with an offscreen GWorld back-buffer
  • CSS 2.1 painting order & z-index stacking contexts

CSS — 150+ properties

  • Custom properties & var()
  • Flexbox — justify-content, order, align
  • Grid V1 — grid-template, gap
  • Gradients, border-radius, box-shadow, opacity
  • transform, text-shadow, counters, aspect-ratio

JavaScript — Duktape ES5

  • Closures, prototypes, regex, JSON
  • Promises via polyfill, deep recursion
  • Live Mandelbrot computed in-page
  • ~6 sec ackermann(3,7) on a 233 MHz G3

Images — all five formats

  • PNG with real per-pixel alpha (lodepng + CopyMask)
  • GIF with palette transparency
  • JPEG, BMP and TIFF decoding
  • QuickTime Graphics Importers as the content handler

Networking

  • Open Transport TCP, plain non-InContext calls
  • HTTP/1.1 + chunked + keep-alive + 3xx follow
  • Connection pooling, 15 s no-progress timeout
  • HTTPS via the Go proxy or native macSSL

Browser chrome

  • Address bar, back / forward / reload / home
  • Status bar, page-info, multi-window
  • Smooth scroll bar & keyboard scrolling
  • Platinum-themed native Carbon UI
// technical constraints

The platform sets the rules.

MacSurf works around them, not against them. This is what building a browser for 1999 actually costs.

01

Cooperative multitasking only

No preemptive threads anywhere. WaitNextEvent drives the UI; Open Transport yields via the Thread Manager.

02

Strict C89

No inline, no // comments, no designated initializers, no for-scope declarations. CW8 compiles nothing more modern.

03

No HTTPS in the browser

Without macSSL, all TLS is handled by the proxy — the Mac speaks plain HTTP and the proxy bridges out.

04

16 MB Carbon partition

libcss allocates from the OS heap and runs out below ~12 MB on real-world pages. Memory is the hard ceiling.

// getting started

Two ways in.

Build the browser on the Mac with CodeWarrior, or stand up the proxy in seconds with a single Go binary.

build the browser
# on Mac OS 9, with CodeWarrior 8 Pro
# cross-compile-clean against Retro68
open MacSurf.mcp
make --target PowerPC

Source stays cross-compile-clean against Retro68 PowerPC GCC for fast Linux-side syntax checks. See the Mac-side build guide and Linux cross-dev workflow.

run the proxy
# one Go binary — no dependencies
cd proxy
go build -o macsurf-proxy
./macsurf-proxy
→ listening on :8080

No config files. No dependencies beyond the standard library. Point the browser's proxy setting at the host and you are on the modern web. See the deploy guide.