Start · Introduction
Introduction
Moonframe is a starter for native desktop apps whose whole window is written in Luau. Rust and GPUI draw it, check it, and keep it safe; every panel, split, toolbar and status bar is a Luau file that reloads as you save, with its state kept.
$ git clone https://github.com/penso/moonframe my-app $ cd my-app $ mise install # Rust, and Zig for the Ghostty terminal $ just run # opens the window on app/
Quick start →Clone, run, edit a file, watch it change.
Your first mod →State, init, update, view.
Component catalogue →Every
ui.* element and use piece.
Build an app →moonframe.toml, profiles, bundles.

app/mods/.A mod is one file
The shell, app/main.luau, places regions, and mods fill them. Each mod has its own state, init, update and view, like an Elm program; mods talk with messages.
-- app/mods/counter/main.luau return mod { region = "left", init = function(previous) return previous or { count = 0 } end, update = function(state, msg) if msg == "add" then state.count += 1 end end, view = function(state, app) return ui.panel { title = "Counter", ui.text(`Clicked {state.count} times`), ui.button { "Add", msg = "add", variant = "primary" } } end, }
Save it and it appears in the left region.
Where things go
| Need | Write |
|---|---|
| A look | a rule in style.luau |
| A reusable piece | components/<name>.luau, used with use "stat" |
| A shell | ui.terminal { id = "main", cwd = "~/code" } |
| Data from the machine | a provider in providers/<name>/, read as app.<name> |
| A sheet or menu | ui.popover { open = state.open, dismiss = "close" } |
| A new kind of element | Rust in crates/, the one change that needs a rebuild |
SandboxedLuau runs with no files, network or process access, a memory cap and an instruction budget. Anything that reaches the machine goes through a provider or an element the host owns.
Platforms
Moonframe is developed on macOS. CI builds, lints and tests it on macOS, Linux (x86_64 and ARM64) and Windows; each release ships a macOS disk image, Linux tarballs and Windows zips, with checksums, Sigstore signatures and GitHub attestations.