raylib examples in jank

209 raylib examples written in jank — native Clojure compiled to a real binary through C++/LLVM, no JVM. They reach raylib as ordinary C++ through (:include "raylib.h") and the cpp/ prefix: no FFI layer, no binding DSL, no generated shim.

A few of them

core 46 · shapes 41 · text 16 · textures 31 · models 29 · shaders 35 · audio 11 — every one of them, with a preview.

Why this is interesting

Jolt and JVM Clojure cross the boundary to C at the call: a call marshals values across, but a raylib struct can otherwise sit in an ordinary variable. jank draws the boundary around the value. A Color here is a real C++ value the compiler tracks, not a handle — and that one difference is what shapes every example in this repo.

How it fits together

flowchart LR
  subgraph ex["209 example namespaces"]
    e["starfield · raymarching · basic-pbr
penrose-tile · vr-simulator · …"] end subgraph sys["jank-raylib-sys — the -sys wrapper"] bb["jank-build.bb builds raylib
with CMake, emits include-dir,
link-dir and link-library"] hh["jank_rlights.h
C-side helpers for what
jank values cannot cross"] end rl["raylib, built from the
vendored submodule"] e -->|"(:include raylib.h) + cpp/ calls"| rl bb --> rl e --> hh hh --> rl

There is no binding layer to maintain, because there is nothing to bind: each example includes the C header and calls raylib directly. Adding an example touches exactly four places — the source namespace, a project.clj profile, a bb.edn task, and a row in the bb/helpers.clj registry.

What's here

No binding layer at all

No FFI DSL, no codegen, no C shim. (cpp/DrawCircle x y r cpp/RAYWHITE) is a C++ call the jank compiler emits directly.

Native, not the JVM

jank compiles through C++/LLVM to a real binary. There is no Java interop to fall back on either — no Math/sin, no format. C's math.h and str take their place.

Self-contained build

raylib is a vendored submodule, built from source by the -sys wrapper. No system raylib, and no third-party Maven or Clojars artifact is fetched.

C-side helpers where jank can't reach

jank_rlights.h adapts raylib's rlights.h into index-based scalar wrappers, so lighting examples need no per-file shim block.

Provable without watching it

A windowed example proves itself unattended with a timed run whose SIGALRM exit is the success signal, plus a grep for the jank/raylib failure vocabulary.

Every example recorded

All 209 carry an animated preview in the catalog, recorded from the real running example rather than mocked up.

Quickstart

git clone --recurse-submodules git@github.com:burinc/b12n-raylib-jnk.git

bb info            # grouped cheat-sheet of everything
bb install         # build raylib + install jank-raylib-sys into ~/.m2
bb starfield       # run one (opens a window)
bb run-all 10      # demo reel: every example, 10s each

Needs the jank compiler with lein-jank 2026.06-1 or newer, a C++ compiler and CMake. babashka gives every example a friendly task; without it each one is a lein with-profile +<name> run away. Released under the zlib license — the same one raylib itself uses.