A keyboard-driven sketching app for macOS and Windows. A big canvas, layered ink strokes, reference images you can drop or paste in, and modifier keys that turn the mouse into a brush, a zoom lens, a size scrubber, or a color picker depending on what you're holding.
Built in C with raylib for rendering and SQLite for storage. One 4096×4096 document, rendered through a paper shader and an ink-compositing shader so strokes feel a little less digital.
Requires Zig 0.15.2+. First build downloads raylib and sqlite sources automatically.
zig build runRuns on macOS and Windows. Clipboard paste uses AppKit on macOS and Win32 on Windows; the Zig build links the right OS frameworks/libs per platform.
- Layered vector strokes. Every stroke is a list of sample points replayed through the ink shader. Undo pops the last stroke. Each layer has its own opacity, visibility, and pan offset.
- Reference images. Drop a file onto the window, or
Cmd-Va screenshot. Reference images live in the same z-stack as stroke layers, so you can slip ink in front of or behind them. - Fluid navigation. Scroll to zoom at the cursor,
Space-drag to pan,1–5for preset zooms,Z-drag to zoom to a rectangle. A minimap fades in whenever you move the view. - Keyboard tools. Hold
Dand drag to scrub brush size. HoldFto open a radial color picker — release over a swatch to pick it. HoldEfor an eyedropper. HoldShiftfor a straight line. Press/for the help overlay. - Autosave. Every completed stroke writes to SQLite at
~/Library/Application Support/Understudy/paintings.db. Save with a name when you want to keep it; load, rename, delete, export as PNG, crop, or resize from the toolbar.
src/
main.c game loop + all keyboard routing
canvas.c/.h layers, strokes, render targets, shader compositing
refimage.h single-header reference-image system
toolbar.c/.h left panel
ui.c/.h modal overlays (save/load/export/crop/resize/help/layer settings)
db.c/.h SQLite schema and I/O
tools.c/.h active tool + brush state
clipboard_mac.m NSPasteboard → PNG bytes (macOS)
clipboard_win.c Win32 clipboard → PNG bytes (Windows)
paper.fs, ink.fs GLSL fragment shaders
See CLAUDE.md for architecture notes.
Written collaboratively with Claude Code, Anthropic's terminal coding agent. Most of the code in this repo was produced by driving Claude through the design: sketching a feature, having Claude propose an approach, trying it, and iterating. The shaders, the ref-image layering, the keyboard-heavy interaction model, and the storage schema all came out of that loop. Any rough edges are mine.