Using X11 to run a modern web browser on a PowerPC Mac
The closest thing to a modern browser a PowerMac can run is ancient forks of Firefox from roughly 2014. The forked browsers like TenFourFox, InterWeb PPC, and AquaFox all ship with band-aid fixes to attempt to cobble together more modern features. Modern browsers, these are not. While a PowerPC Mac can't run a modern browser in OS X, it can display one.
This isn't OS X specific even, as X11 exists on multiple Unix-like systems and these instructions should be adaptable to other Unix-like systems as well, like SunOS.
The trick: let another computer do the heavy lifting (Firefox + modern TLS + modern JS), and have the PowerMac act like a dumb terminal that just draws windows and sends keyboard/mouse input. For this example, I'll be using a Raspberry Pi 5 with an NVMe expansion (aka Hat), but any Linux computer will do. If you don't have an always on Linxu box, the Raspberry Pi 5s are fast enough and can be had for about $100~ for the 8 GB version (recommended for this project), consume only about 4 watts idling and NVMe is entirely optional, if you're looking to do this on the cheap, just get a 32+ GB MicroSD card. Plus, you'll be able to do plenty more with a Pi 5 like PiHole for DNS level adblocking, hosting docker etc.
This project uses old-school X11 remote display technology, not VNC which largely streams pixels. The way X11 works is it sends commands like "create a window, draw text here, render this image, handle this click." The results in real-time window updates on the PowerMac, and functionality that feels like an application running (almost) natively on the Mac.
What you need
- Linux computer on the same local network as your Mac
- A PowerPC Mac running OS X (I'm on 10.5 Leopard but this should work in 10.4 Tiger)
- XQuartz installed on the Mac (Leopard's built-in X11 is old and may not behave)
- SSH access to the Pi
Step 1: Install X11 + Firefox on the Raspberry Pi
On the Pi:
sudo apt update
sudo apt install -y firefox-esr x11-apps x11-utilsx11-apps gives you quick sanity-test tools like xclock. x11-utils as well as xdpyinfo so you can confirm you're actually communicating with the Mac's X server.
Step 2: Install XQuartz on the PowerPC Mac
Leopard shipped with X11, but it's old. When I tried to use it, it didn't play nice with the Pi. Install XQuartz's X11 instead.
Grab XQuartz 2.6.1 (this appears to be the last release for Leopard):
https://www.xquartz.org/releases/XQuartz-2.6.1.html
If on Tiger, you'll probably need to experiment with older XQuartz versions; See the archive
Install it, then launch X11. You'll get an xterm window (this is NOT the same as the Mac Terminal). If it doesn't launch with a terminal open, from the menu select New Xterm window.
Step 3: Allow network clients
We'll have to make some security concessions during setup to eliminate any possible complications due to network restrictions.
In the OS X preferences, open System Preferences > Security & Privacy > Firewall, then click the lock to make changes. Click Firewall Options... and disable it.
In X11:
- Open X11 Preferences
- Go to the Security tab
- Check Allow connections from network clients
Then restart X11 (quit and re-open it). This setting often doesn't fully take effect until you relaunch.
Next, in the X11 xterm, run:
xhost +That basically says "anyone on my LAN can open windows on my X server." You can be more strict, but for a retro Mac on a home LAN, this shouldn't be too much of an issue. Once you've set up X11 you can always return to the security settings and tighten things back up.
Step 4: Confirm what X11 port you're listening on
X11 uses port 6000 + display number.
:0= port6000:1= port6001- etc.
From the X11 xterm on the Mac:
netstat -an | egrep '\.600[0-9] ' | egrep 'LISTEN|listen'If you see 6000, you're on display :0. If you see 6001, that's display :1.
If you see a higher than 6001, often this will create issues; reboot the Mac and try again.
Step 5: From the Pi, confirm you can reach the Mac's X11 port
On the Pi, test the port (replace with your Mac's IP and the port you saw above):
nc -vz 192.168.50.134 6001If it connects (doesn't time out), you're almost done.
Now confirm X11 is really responding:
DISPLAY=192.168.50.134:1 xdpyinfo | headYou should get output that looks similar to:
name of display: 192.168.50.134:1
version number: 11.0
vendor string: The X.Org Foundation
...Step 6: Test a simple X app (the victory lap)
On the Pi:
DISPLAY=192.168.50.134:1 xclockIf a little clock window pops up on the PowerMac, congrats — you've got remote X working.
Step 7: Launch Firefox ESR on the Pi, display it on the Mac
On the Pi:
DISPLAY=192.168.50.134:0 \
GDK_BACKEND=x11 \
MOZ_DISABLE_WAYLAND=1 \
MOZ_DBUS_REMOTE=0 \
firefox-esr --new-instance --no-remoteA quick breakdown of the flags:
DISPLAY=...tells the Pi where to draw the GUI (your Mac's XQuartz display), the:0specifies the display number, which we confirmed earlier. 0 = port 6000, 1 = port 6001, etc.GDK_BACKEND=x11forces GTK onto X11MOZ_DISABLE_WAYLAND=1avoids Wayland paths on the PiMOZ_DBUS_REMOTE=0+--new-instance --no-remoteprevents Firefox from trying to "reuse" an existing local GUI instance
If you do not see anything, try flipping between :0 and :1 based on what your Mac is actually listening on (remember: :0 => 6000, :1 => 6001).
Troubleshooting
While AI is a bit of scourge, the recent models of Claude and Chat GPT are excellent at debugging terminal scripts. Even as an advanced technical user, I used it quickly debug my issues when working on this project as I'm new to X11, as I was able to display xclock but not Firefox ESR.
OS X is a bit janky, I'd highly recommend 10.5 as it's supported by xQuartz officially, but I've heard that it can be hacked to work on Tiger. Ports can get "occupied" and cause issues, so a reboot can sometimes help.
Bonus: Launching Firefoxwith X11 from the PowerMac with a script
To make life more convenient, it's pretty easy to make a script to launch FireFox X11 from your PowerPC Mac. One gotcha: Leopard's built-in SSH can be too old to communicate to modern OpenSSH a modern system. You can lower your security settings on said system but the smarter move is to update SSH to a newer version. I'm using a homebrew OpenSSH binary. To install OpenSSH, install TigerBrew onto your 10.4/10.5 Mac.
#!/bin/sh
# Assumes XQuartz is already running on the Mac.
# Allows the Pi to open X11 windows, then SSH into the Pi and launch firefox-esr.
set -eu
PI_HOST="192.168.50.224"
PI_USER="me"
detect_mac_ip() {
ip="$(ipconfig getifaddr en0 2>/dev/null || true)"
[ -n "${ip:-}" ] && { echo "$ip"; return; }
ip="$(ipconfig getifaddr en1 2>/dev/null || true)"
[ -n "${ip:-}" ] && { echo "$ip"; return; }
echo ""
}
MAC_X11_HOST_IP="$(detect_mac_ip)"
if [ -z "${MAC_X11_HOST_IP:-}" ]; then
echo "ERROR: Could not detect this Mac's LAN IP."
exit 1
fi
BREW_PREFIX="$(brew --prefix)"
SSH_BIN="${BREW_PREFIX}/opt/openssh/bin/ssh"
if [ ! -x "$SSH_BIN" ]; then
echo "ERROR: Expected brewed ssh at: $SSH_BIN"
exit 1
fi
# Wide open version (matches the blog post steps):
# DISPLAY=:0 xhost +
#
# Slightly less wild: allow only the Pi:
DISPLAY=:0 xhost +"$PI_HOST" >/dev/null 2>&1
"$SSH_BIN" -t "${PI_USER}@${PI_HOST}" "
export DISPLAY='${MAC_X11_HOST_IP}:0'
export GDK_BACKEND='x11'
export MOZ_DISABLE_WAYLAND=1
export MOZ_DBUS_REMOTE=0
exec firefox-esr --new-instance --no-remote
"Then run it:
chmod +x launch-x11-firefox.sh
./launch-x11-firefox.shYou can take this even further by enabling AFP on your Raspberry Pi and serving up the downloads as a network volume for your Mac.
That's it
Your 2003 PowerMac is now "running" a modern browser… in the same way a monitor is "running" Photoshop. It's stupid, it's fun, it's absolutely not efficient, and it works way better than it has any right to.
Updates
2026-01-03: Cleaned up language and syntax highlighting, added troubleshooting tips and added links to retro browsers.