The easiest way to install ORCA is via LuaRocks:
luarocks install orcaThen in your Lua code:
local orca = require "orca"
local ui = require "orca.UIKit"See LUAROCKS.md for detailed LuaRocks installation and usage instructions.
To install the required dependencies on Linux, run the following commands:
sudo apt update && sudo apt install -y \
libpng-dev \
libfreetype6-dev \
libjpeg-dev \
liblua5.4-dev \
libxml2-dev \
liblz4-dev \
zlib1g-dev \
libcurl4-openssl-dev \
libwayland-dev \
libegl1-mesa-dev \
libgles2-mesa-devFor Fedora, use:
sudo dnf install -y \
libpng-devel \
freetype-devel \
libjpeg-turbo-devel \
lua-devel \
libxml2-devel \
lz4-devel \
zlib-devel \
libcurl-develFor Arch Linux, use:
sudo pacman -S libpng freetype2 libjpeg-turbo lua libxml2 lz4 zlib curlTo install dependencies on macOS, use Homebrew:
brew install libpng freetype jpeg-turbo lua libxml2 lz4 zlib curl pkg-configNote: If pkg-config fails to find packages, you may need to run:
brew link --overwrite freetype jpeg-turboBefore building, you must initialize and update the git submodules to fetch the platform package:
git submodule update --init --recursiveTo build the project, run:
makeAfter building, you can run the example application:
build/bin/orca samples/ExampleOr simply use:
make exampleThe Example sample uses SVG icons sourced from Lucide and the Lucide GitHub repository.
See samples/Example/Icons/README.md for the icon asset notes.
ORCA supports multiple approaches for building applications, each with their own strengths:
- MoonScript: Best for app-building with hot reloading and rapid development
- XML: Editor-friendly for graphics-heavy applications like instrument clusters (Editor is currently work-in-progress)
- Pure Lua: Full control with traditional Lua syntax
XML approach (UI screen definition):
<?xml version="1.0"?>
<!DOCTYPE Screen SYSTEM "https://corepunch.github.io/orca/schemas/orca.dtd">
<Screen Name="Application" Height="768" Width="1024">
<TextBlock Name="TextBlock" FontSize="40" LayoutTransform="400 20 0 1 1" Text="Hello World"/>
<ImageView Name="Image" Source="Example/Images/peacock"/>
</Screen>MoonScript approach (clean and expressive):
class Application extends Screen
Height: 768
Width: 1024
body: =>
textblock ".text-block", Text: "Hello World", FontSize: 40
imageview ".image", Image: "Example/Images/peacock"✅ More concise syntax
✅ Native language constructs instead of markup
✅ Better for programmatic UI logic
Note: XML remains useful for visual editor workflows and is still required for project configuration files.
Let's compare the same UI component in both languages using ORCA's framework:
Pure Lua with ORCA (still verbose):
local StackView = require("orca.UIKit").StackView
local ContactCard = StackView:extend {
apply = function(self)
return "contact-card"
end,
body = function(self)
img { src = "https://picsum.photos/64" }
stack(".flex-col", function()
p(".contact-card-title", self.user.name)
p(".contact-card-description", "@" .. self.user["$id"])
end)
end
}MoonScript with ORCA (clean and elegant):
import StackView from require "orca.UIKit"
class ContactCard extends StackView
apply: => "contact-card"
body: =>
img src: "https://picsum.photos/64"
stack ".flex-col", ->
p ".contact-card-title", @user.name
p ".contact-card-description", "@"..@user["$id"]-
Native Class Syntax
- No need to call
:extend()explicitly extendskeyword is cleaner than method calls@shorthand forselfreduces noise
- No need to call
-
Implicit Returns
- No explicit
returnstatements needed - Functions automatically return their last expression
- No explicit
-
Cleaner Method Definitions
-- Lua apply = function(self) return "contact-card" end
vs
-- MoonScript apply: => "contact-card"
-
Import/Destructuring
import Account from require "model" import Application from require "routing"
vs
local model = require("model") local Account = model.Account local routing = require("routing") local Application = routing.Application
-
Arrow Functions & String Interpolation
- Concise route definitions
- Less punctuation clutter
- More readable nested callbacks
MoonScript makes routing declarations elegant:
class App extends Application
"/": => Layout page.HomePage
"/send-money": => Layout page.SendMoney
"/settings": => Layout page.Settings
"/tweets": => Layout page.Tweets
"/new-tweet": => Layout page.NewTweet
"/user/:user": => Layout page.ContactDetails, @params
"/transaction/:transaction": => Layout page.TransactionDetails, @params
"/search": => SearchPage!Same in pure Lua:
local App = Application:extend({
["/"] = function(self)
return Layout(page.HomePage)
end,
["/send-money"] = function(self)
return Layout(page.SendMoney)
end,
["/settings"] = function(self)
return Layout(page.Settings)
end,
["/tweets"] = function(self)
return Layout(page.Tweets)
end,
["/new-tweet"] = function(self)
return Layout(page.NewTweet)
end,
["/user/:user"] = function(self)
return Layout(page.ContactDetails, self.params)
end,
["/transaction/:transaction"] = function(self)
return Layout(page.TransactionDetails, self.params)
end,
["/search"] = function(self)
return SearchPage()
end
})Notice: 8 lines in MoonScript vs 24 lines in Lua for the exact same routing logic!
Even with ORCA's simplified extend() API, MoonScript gives you:
- ✅ 40-60% less code than equivalent Lua
- ✅ Cleaner class definitions without manual table construction
- ✅ Compiles to readable Lua (easy to debug, uses your
extend()under the hood) - ✅ Full Lua compatibility (use any Lua library)
- ✅ Perfect for UI/DSL code with clean component structure
Explore the sample applications to see these approaches in action.
LuaRocks is Lua's package manager, and MoonScript is a programming language that compiles to Lua with a more elegant, Python-like syntax.
First, install LuaRocks:
# Ubuntu/Debian
sudo apt install -y luarocks
# Fedora
sudo dnf install -y luarocks
# Arch Linux
sudo pacman -S luarocksThen install MoonScript via LuaRocks:
sudo luarocks install moonscriptUsing Homebrew:
brew install luarocks
luarocks install moonscriptCheck that MoonScript is installed correctly:
moonc -vORCA uses XML files to define the API interface between C modules and Lua. See the Module XML Guide for comprehensive documentation on creating and maintaining module XML files.
To regenerate C bindings and documentation from module XML files:
make modulesFor better XML editing experience in VSCode with autocomplete and validation:
-
Install the Red Hat XML extension in VSCode
-
Create a
.vscode/settings.jsonfile in your project directory (e.g.,samples/Example/.vscode/settings.json):
{
"xml.fileAssociations": [
{
"pattern": "**/Prefabs/*.xml",
"systemId": "../../tools/schemas/orca.dtd"
},
{
"pattern": "**/Screens/*.xml",
"systemId": "../../tools/schemas/orca.dtd"
},
{
"pattern": "**/Materials/*.xml",
"systemId": "../../tools/schemas/orca.dtd"
},
{
"pattern": "**/Shaders/*.xml",
"systemId": "../../tools/schemas/shader.dtd"
}
]
}Note: The paths in systemId are relative to the project directory. Adjust them based on your project structure relative to the tools/schemas/ directory.
This project is licensed under the MIT License - see the LICENSE file for details.