Hey! Hope you're doing well.

So, I went down a fascinating rabbit hole last night with Garnet—you know, that modern graphical toolkit for Common Lisp that creates native macOS interfaces. I love Common Lisp. I love the REPL, the live coding, the feeling of building a system from the ground up. But for years, there was one thing that always broke the spell: the moment I needed to show my work to someone who wasn't comfortable in a terminal. Building a graphical interface for a Lisp app usually meant wrestling with low-level C bindings or settling for a clunky Tk window that looked like it was from 1995. It worked, but it never felt good.

So when I stumbled across Garnet, described as a "modern graphical toolkit" for Common Lisp that creates native macOS interfaces, I was deeply skeptical. Another FFI wrapper promising the moon? I'd been down that road. But the project page mentioned it was a revival of work from Carnegie Mellon, built on a constraint system and designed to feel like Lisp. That was enough to make me clone the repo and give it a shot on my M2 MacBook Air running macOS Sequoia.

The Initial Stumble: Quicklisp and Dependencies

My first attempt was a mess. I fired up SBCL, tried to load the system via Quicklisp, and immediately got a wall of errors about missing frameworks and compilation failures. The problem wasn't Garnet itself—it was my environment. I hadn't installed the full Xcode command-line tools, which are required for compiling any native code that talks to Apple's APIs. A quick xcode-select --install in the terminal fixed that, but it was a classic "Lisp on macOS" gotcha. For a complete overview of setting up a development environment, Apple's own guide on the command-line tools is the place to start.

After a successful (ql:quickload :garnet), I loaded the examples. And then, I saw it: a native-looking Mac window, complete with smooth fonts, Dark Mode support, and a responsive interface—all controlled from my Lisp REPL. No C++ compilation steps, no bridge files. Just Lisp.

The "Aha!" Moment: The Constraint System

I decided to build a simple, real-time data monitor for a personal project—a little window that would watch a folder and display the sizes of files as they changed. In a normal toolkit, I'd be writing event handlers and manual update calls. With Garnet, I used their KR (constraint) system.

I defined a file-list object and a text-output widget. I set the widget's text property to a formula: (format nil "~{~A: ~A bytes~%~}" (map 'list (lambda (f) (list (file-namestring f) (file-size f))) (directory "my-folder/*.*"))). The magic? I didn't write a single line of code to update the display. I just told Garnet that the text depended on the folder's contents. Every time the REPL ran or I triggered a rescan, the window updated automatically. It felt like using a spreadsheet, but for UI.

I found this page with the system requirements that mentioned the Xcode dependency: the resource I used. (Wait, that's the wrong link—let me find the right one. Actually, the Garnet GitHub repo has all the setup details, and the Common Lisp HyperSpec is essential reading for anyone diving deep into Lisp.)

What Worked (and What Didn't)

  • The Lapidary Builder: I visually designed a control panel for the monitor. It generated the Lisp code, which I then tweaked in the REPL while the app was running. That "change-and-see" loop is pure joy.
  • Native Feel: The widgets are AppKit widgets. Scroll bars behave correctly, the app icons show in the Dock, and it respects the system accent color. No "uncanny valley" of cross-platform toolkits.
  • The Learning Curve: The constraint system is powerful but takes time to internalize. My first few interfaces had weird recursive update loops until I understood how dependencies propagate.

Is Garnet for You?

If you're a Lisp hacker who's been avoiding GUI work, or if you need to build a native Mac tool and want to use Lisp, Garnet is a revelation. It brings the interactive, flexible Lisp development experience to the world of polished desktop applications. It's not for building the next Photoshop, but for custom tools, research interfaces, and internal utilities, it's a game-changer. And if you're exploring the ecosystem of powerful, specialized software for macOS, it's fascinating to see what's possible when you combine a classic language with modern native frameworks. For me, it finally closed the gap between the Lisp I love and the Mac I use every day.

Let me know if you try it!

Talk soon

Edit

Pub: 19 Feb 2026 19:45 UTC

Edit: 21 Feb 2026 17:54 UTC

Views: 3