OPEN SOURCE · 2026 · MIT LICENSE
clarus/
A small, compiled, event-driven language for building native System 6/7 applications on 68k Macintosh computers — with a self-hosting compiler that emits 68k machine code directly and also runs on the Mac itself.
- compiler
- clarusc, written in Clarus
- targets
- 68k Mac · System 6/7
- outputs
- native .APPL · C99 for host builds
- size
- 65.8k lines of Clarus
- tests
- 462 golden-test programs
- license
- MIT
## why
Writing a Mac application in 1988 meant learning dozens of Toolbox calls — system provided subroutines built into the OS or the ROM — before a window appeared on screen. Clarus aims for the opposite: a standard app needs zero Toolbox knowledge. Programs are typed declarations — windows, menus, records — plus event handlers.
When a program does need the Toolbox, curated declarations from Inside Macintosh are one import away. System 7 features also sit behind a runtime check with a System 6 fallback.
window Game {
title: "Bounce"
size: 200, 200
canvas Board { at: 0, 0; fill: both; buffered }
var x: fixed = 10.0
var dx: fixed = 2.0
}
every 1 ticks {
var g: Game = Game.front
if g != nil {
g.x = g.x + g.dx
if g.x > 190.0 or g.x < 0.0 { g.dx = -g.dx }
g.Board.clear()
g.Board.fillCircle(int(g.x), 100, 8)
}
}
## design
- No native C compiler or assembler needed. The clarusc compiler generates 68k code, runs a peephole pass, encodes instructions with its own assembler, and writes a multi-segment application with its resources (alerts, dialogs, icons, version info). The third-party
vasmassembler is used by the test suite to verify the generated machine code. - Self-hosting. The compiler is written in Clarus. It was first built by a compiler written in Go, then ported file by file until the two matched byte for byte across the test corpus. Today the three-stage bootstrap reaches a byte-identical fixed point, and the Go compiler is gone.
- The compiler runs on the Mac.
ClarusC.APPLcompiles Clarus programs on the Macintosh itself, with the runtime's source and precompiled IR baked into its resources. - One language, two backends. The same lowered IR — intermediate representation — feeds a C backend for fast host builds and testing, and the native 68k backend. A shared UI descriptor keeps windows and menus identical on both.
## how it was built
I built it with Claude Code in a design-first workflow. The first step was creating an initial language design and goals document by hand. Once I had that in place my regular AI workflow followed the same pattern: first a brainstorming session to work out the details of a new feature, then the creation of a written specification, followed by the creation of a written implementation plan, and finally the actual implementation using a team of subagents.
Every step involved me directing the design and reviewing the generated code. It took about two months of development and around 1,300 commits to complete the original design goals. Using the language to build a real world application — a BBS server — helped iron out problems and improve usability as well.
Testing runs at two speeds: a quick gate of golden tests on every change, and a merge gate that boots Mini vMac and Snow emulators, injects scripted events, and compares framebuffer snapshots against the host build. The compiled applications also run on real hardware.