When I tell someone I built an X server for the Mac, the first question is almost always: “but doesn’t XQuartz already do that?” The honest answer is yes, mostly. XQuartz works. I used it for years.
I also have a Linux desktop right next to my Mac, and the same problem
exists there. The X11 tools for dealing with it on Linux are messy:
xrandr --output ... --scale 2x2 for server-side bilinear upscaling,
Xft.dpi in .Xresources for toolkit fonts, GDK_SCALE and
QT_SCALE_FACTOR env vars for individual toolkits. No single switch
covers everything. Pure-X11 apps like xterm ignore most of them. The ones
that respond often look blurry because xrandr --scale is a post-process
upscale, not a real per-app rescale. I never found a workable solution on
Linux either, so I went into this knowing the X server side was where
the fix needed to happen.
The reason I built macXserver instead of just using XQuartz comes down to two things: window scaling and display quality. On a 5K Studio Display an XQuartz xterm at native resolution is unreadable, and the standard workaround (drop the whole Mac desktop to a non-native resolution while you’re using X) is worse than the problem. The core X11 font path also defaults to bitmap fonts, so the text inside that xterm looks like 1995 even at a readable size. Those two things together made the daily experience unworkable for me.
Everything else in this article followed from chasing those two fixes. The rest of the comparison is interesting (extensions, transports, capture and replay, Mac window integration), but the visual story is what made me build my own instead of working around XQuartz.
If you have any doubt about the display quality, look at the screenshots on this site. Or better yet, just try it. It’s free.
What follows is the honest scorecard. Parity items at the top, the places macXserver pulls ahead next, the places it loses next, and the categories that aren’t in macXserver’s mission at all at the bottom. By the time you’ve read the four tables you’ll know which of the three servers fits your situation.
The three servers, briefly
MIT X11R6. The reference implementation. Thirty years of accumulated bug-fixes against thousands of clients. About a million lines of C. Runs on Unix; doesn’t target macOS at all.
XQuartz. The Mac port of the X.Org server. Around 15 years old, actively maintained. About 1.5 million lines of C inherited from X.Org. Runs on macOS as a separate app. Used by every Mac engineer who needs Firefox-from-Linux or GIMP-from-Linux running locally.
macXserver. Built in 30 days with Claude Code as an agentic coding partner. About 30,000 lines of Swift. Runs as a Mac app. Specifically targets vintage X clients from Unix workstations of the 80s and 90s.
Three different starting points, three different optimization targets.
Parity
There are a handful of things all three do at roughly the same level. None of these are where the comparison is interesting.
| Capability | MIT X11R6 | XQuartz | macXserver |
|---|---|---|---|
| Core X11 protocol over TCP | yes | yes | yes |
| Basic XLib client compatibility | yes | yes | yes |
| Window creation, mapping, drawing | yes | yes | yes |
| Keyboard and mouse routing | yes | yes | yes |
| Multi-client serving on one display | yes | yes | yes |
| PRIMARY selection (X-style cut/paste) | yes | yes | yes |
If you launch xterm against any of these three, it pops a window and accepts keystrokes. The differentiation is everywhere else.
Where macXserver pulls ahead
These are the features I built specifically because the existing options didn’t have them, or had them in a form that didn’t fit the use case I cared about. They all serve the “vintage X on modern Mac” mission.
| Capability | MIT X11R6 | XQuartz | macXserver |
|---|---|---|---|
| Anti-aliased core X11 fonts | no (bitmap) | only via Xft (client opts in) | yes, Core Text, always |
| Per-window display scaling (integer 1×/2×/3×) | no | no | yes |
| First-class macOS windows | N/A | partial (rootless) | yes, NSWindow per top-level |
| Mission Control / Cmd-Tab / Spaces participation | N/A | partial | yes |
| Optional Motif-style window frame | N/A | no | yes |
| Built-in session capture / replay | no | no | yes (.xtap) |
| In-app resource editor with themes | no | no | yes |
| In-app font mapping editor | no | no | yes |
| Remote launcher (Sun → Mac status menu) | N/A | no | yes |
| Codebase a single engineer can read in a sitting | no | no | yes |
The two top items in that table are the ones that drove the whole project: per-window display scaling and anti-aliased core fonts. Together they’re the difference between an X window that looks like 1995 on a Retina display and an X window that looks like a Mac app at any scale.
XQuartz’s options for a Studio Display are “unreadable at native resolution” or “drop the whole Mac to a non-native resolution while you’re using X.” macXserver picks an integer scale per X window (1×, 2×, or 3×) without touching anything else on the desktop. The Mac at native Retina, the X xterm at the size I want, no mode switching. Combined with the font path (every X font request resolves to a Core Text font at integer pointSize, the server reports back the rendered metrics, and the cell follows the font), the result sits comfortably next to an iTerm2 window at any scale.
The Mac-integration items (Mission Control, Cmd-Tab, real NSWindow per top-level) are the second reason. They were a smaller motivator than the visual quality but they’re a real upgrade once you have them. XQuartz’s rootless mode puts X clients in their own window-management space that doesn’t fully participate in macOS’s window management. macXserver makes every X top-level a real Mac window with a real NSWindow behind it, and the Mac window-management features follow from that automatically.
Where macXserver loses
These are the places MIT and XQuartz win cleanly. There’s no spin here.
| Capability | MIT X11R6 | XQuartz | macXserver |
|---|---|---|---|
| X extension breadth | 30+ extensions | 30+ extensions | SHAPE only (others decoded for capture, not implemented) |
| GLX (OpenGL through X) | yes | yes | no |
| Network transports | TCP + Unix socket | TCP + Unix socket | TCP only |
| Xauth (X authentication) | yes | yes | no (local-only by design) |
| Breadth of clients tested | thousands | thousands | tens |
| Years of edge-case bug fixes | 30+ | 15+ (inherited) | 30 days |
| Modern Linux toolkits (GTK4, Qt6) | yes | yes | untested |
| Input methods (XIM, IBus, CJK) | yes | yes | no |
| Server-side compositor extension | yes | yes | no |
The opcode count comparison is the easiest one to be misleading about. macXserver implements 138 opcodes counting extensions, which sounds comparable to the references on paper. They aren’t equivalent. The references have decades of edge-case fixes in each of those handlers; macXserver has 30 days. For the test corpus I built (xterm, quickplot, the CDE dt-apps, xcalc, xeyes, xclock, x11perf), every opcode has been exercised against real clients. For modern GTK4 apps, who knows. I haven’t tested them and don’t have plans to.
If you want to run a current Linux desktop on your Mac, you want XQuartz. That’s what it’s for. macXserver isn’t.
Not in the mission
These are categories that the references handle and macXserver deliberately does not. The list isn’t apologetic; the scope choice is what made building this in 30 days possible.
| Capability | macXserver scope |
|---|---|
| Running modern Linux desktops (GNOME, KDE, Wayland-via-Xwayland) | not in mission |
| GLX / OpenGL / GPU-accelerated X rendering | not in mission |
Remote X display forwarding (SSH -X from Linux to Mac) | not in mission |
| Linux app compatibility (Firefox, GIMP, modern Qt/GTK apps) | not in mission |
| Input methods for CJK / RTL text entry | not in mission |
| Headless / framebuffer rendering | not in mission |
| Performance-critical (compositor-style) workloads | not in mission |
| Replacing XQuartz for general Linux engineering workflow | not in mission |
The mission for macXserver is narrow on purpose: take an X client from a real Unix workstation of the 80s or 90s, display it on a modern Mac at modern fidelity. Most of the categories above are within range of XQuartz and outside the scope of what I set out to build.
If you keep that mission in mind, the comparison stops feeling like a fight. macXserver and XQuartz solve different problems. The places they overlap are the parity items above. Past the overlap, each one is doing its own thing.
The honest summary
If you weigh the comparison by total feature surface, the references win. That’s true and not surprising. Thirty years and fifteen years of accumulated work beats thirty days. If you weigh by how well it does the specific job I care about, macXserver does better. Because the job I care about is one the references weren’t built for.
Both of those framings are honest. The trap to avoid is the third one, where you pick whichever metrics happen to show macXserver winning and present them as if they were the full picture. That’s the cherry-pick vendor benchmark slides used to live on in the 90s. Don’t do that.
The simple test for “is macXserver right for you” is one question. Do you have a vintage Unix workstation (or an emulated one) whose X clients you want to display on a modern Mac? If yes, macXserver is built for that. If no, you probably want XQuartz, and that’s fine.
For the record, I still use XQuartz when I need it. macXserver doesn’t replace it. It sits next to it on my Mac and gets used when the X client is from a Sun.