A re-frame inspired desktop UI framework built on Odin, Raylib, and LuaJIT.
Write reactive desktop apps in Fennel (or Lua) with the same dataflow model that makes re-frame a joy: single state atom, event-driven updates, path-tracked subscriptions, declarative effects. No browser, no Electron, no JS bundler.
Experimental. This project is under active reboot. APIs will change.
| Layer | Technology |
|---|---|
| Host / renderer | Odin + Raylib |
| Scripting | LuaJIT (Lua 5.1) |
| App language | Fennel (or plain Lua) |
| AI interface | HTTP dev server |
The easiest way to start is with redin-cli:
# Install the CLI (requires Babashka)
curl -sL https://raw.githubusercontent.com/sstoehrm/redin-cli/main/install.sh | bash
# Create a Fennel project
redin-cli new-fnl my-app
cd my-app
./redinw main.fnl
# Or a Lua project
redin-cli new-lua my-appThe CLI downloads a pinned redin binary into .redin/ — no build tools needed. See redin-cli help for all commands.
The one-step path is ./setup.sh, which installs system packages (via apt / dnf / pacman / brew), pulls submodules, and runs ./build-dev.sh. The manual equivalent is below.
# Prerequisites (Ubuntu/Debian)
sudo apt-get install -y luajit libssl-dev \
libgl1-mesa-dev libx11-dev libxrandr-dev libxi-dev \
libxcursor-dev libxinerama-dev
# Initialize submodules (lib/odin-http)
git submodule update --init --recursive
# Dev build (bakes in REDIN_DEV / REDIN_PROFILE / REDIN_TRACK_MEM)
./build-dev.sh
# Run — dev server starts because REDIN_DEV is compiled in.
# Exactly one positional argument is accepted; extra args exit 2.
./build/redin examples/kitchen-sink.fnlFor a release-stripped binary (no dev server, no profile, no tracker), use bare odin build instead:
odin build src/cmd/redin -collection:lib=lib -collection:luajit=vendor/luajit -out:build/redin| Dependency | Purpose | Required |
|---|---|---|
| Odin (nightly) | Compiles the host/renderer | Yes |
| Raylib | Bundled with Odin | -- |
LuaJIT (luajit) |
Runs tests, AOT compiles Fennel; the C library is statically linked from vendor/luajit/ so libluajit-5.1-dev is not required |
Yes |
OpenSSL (libssl-dev) |
HTTPS support via odin-http | Yes |
OpenGL + X11 dev headers (Linux only — libgl1-mesa-dev, libx11-dev, libxrandr-dev, libxi-dev, libxcursor-dev, libxinerama-dev) |
Required by Odin's bundled Raylib at link time | Yes (Linux) |
lib/odin-http submodule |
Async HTTP client used by redin.http |
Yes |
# Fennel runtime tests
luajit test/lua/runner.lua test/lua/test_*.fnl
# Build check
odin build src/cmd/redin -collection:lib=lib -collection:luajit=vendor/luajit -out:build/redinUI integration tests additionally need Babashka (bb), and xvfb for headless runs:
sudo apt-get install -y xvfb
bash test/ui/run-all.sh --headlesssrc/cmd/redin/ Thin CLI entry (package main)
main.odin Arg parsing, calls redin.run
src/redin/ Importable framework (package redin)
runtime.odin Public API + main loop
render.odin Raylib renderer
bridge/ Lua/Fennel bridge
canvas/ Canvas provider system
input/ Input handling
types/ Shared type definitions
src/runtime/ Fennel runtime modules
examples/ Demo apps
test/lua/ Fennel unit tests
test/ui/ UI integration tests (Babashka)
.claude/skills/ Claude Code development skills
docs/ Documentation