LuaJIT language bindings for wxWidgets via kwxFFI, enabling cross-platform GUI applications that render with native controls on Windows, macOS, and Linux.
Do not use this Lua/wxWidgets interface in production.
- The kwxFFI ABI interface is not stable and can change without warning.
- Very little testing has been done, and won't be until late Q2 of 2026.
- API surface may change as idioms are refined.
kwxLuaJIT provides a two-layer binding architecture:
- FFI Layer (
wx/*_gen.lua) — Auto-generated by kwxgen. Raw LuaJIT FFI class wrappers withffi.cdefdeclarations mapping directly to kwxFFI C function exports. One file per wxWidgets class. - Wrapper Layer (
lua/wx/init.lua) — Thewxmodule. Convenience constructors with sensible defaults, Lua-friendly method overrides, runtime constants, and the event callback bridge.
Users work with the wx module. The generated *_gen.lua files are available for direct access when needed.
Lua code → wx module (lua/wx/) → *_gen.lua (FFI declarations) → kwxFFI (C functions) → wxWidgets (C++)
-- examples/hello.lua - Hello World wxWidgets application in Lua
local wx = require("wx")
-- Create application (wxApp is managed by the C++ launcher)
local app = wx.App()
-- Create main frame with standard system buttons
local frame = wx.Frame(nil, "kwxLuaJIT Demo", -1, -1, 800, 600,
wx.DEFAULT_FRAME_STYLE)
-- Status bar
frame:CreateStatusBar()
frame:SetStatusText("Welcome to kwxLuaJIT")
-- Panel holds all controls
local panel = wx.Panel(frame)
-- Vertical sizer for layout
local sizer = wx.BoxSizer(wx.VERTICAL)
local label = wx.StaticText(panel, "Welcome to kwxLuaJIT!")
local button = wx.Button(panel, "Click Me")
-- Connect button click event to a Lua function
button:Connect(wx.EVT_BUTTON, function()
wx.MessageBox("Hello from Lua!", "kwxLuaJIT")
end)
-- Add controls to sizer
sizer:Add(label, 0, wx.ALL, 10)
sizer:Add(button, 0, wx.ALL + wx.ALIGN_CENTER, 10)
panel:SetSizer(sizer)
frame:Show(true)
frame:Center()
app:MainLoop()More examples are in the examples/ directory.
Metatable chaining mirrors the wxWidgets C++ class hierarchy. Every object carries a _ptr field (opaque void*) and inherits methods through the chain:
wxEvtHandler
└── wxWindow
├── wxTopLevelWindow
│ ├── wxFrame
│ └── wxDialog
├── wxPanel
├── wxButton
├── wxStaticText
├── wxTextCtrl
├── wxCheckBox
├── wxChoice
├── wxListBox
└── wxComboBox
wxSizer
├── wxBoxSizer
├── wxFlexGridSizer
└── wxGridSizer
All objects are created through wx.* convenience constructors or the generated *_gen.Create(...) functions directly.
| Entity | Convention | Example |
|---|---|---|
| User-facing module | wx |
local wx = require("wx") |
| Generated modules | <classname>_gen |
wxframe_gen, wxbutton_gen |
| Convenience constructors | wx.ClassName(...) |
wx.Frame(...), wx.Button(...) |
| Methods | PascalCase |
:Show(), :Connect(), :SetSizer() |
| Constants | wx.CONSTANT_NAME |
wx.EXPAND, wx.DEFAULT_FRAME_STYLE |
| Event types | wx.EVT_* |
wx.EVT_BUTTON, wx.EVT_CLOSE |
| Raw FFI exports | expwx<NAME> |
expwxID_ANY, expEVT_BUTTON |
Events are connected with :Connect() (also aliased as :Bind()):
-- Connect a named or anonymous function
button:Connect(wx.EVT_BUTTON, function(evt)
print("clicked")
end)
-- Disconnect by callback id
local cb_id = button:Connect(wx.EVT_BUTTON, handler)
button:Disconnect(cb_id)
-- Disconnect all handlers for an object
window:DisconnectAll()Event types are resolved lazily — wx.EVT_BUTTON triggers a single FFI call on first access and is then cached as a plain integer.
Lua is widely used for scripting, configuration, and rapid prototyping, but native GUI options are scarce. kwxLuaJIT combines LuaJIT's zero-overhead FFI with wxWidgets' native rendering: one small executable, native look on every supported platform, no separate Lua or wxWidgets installation required.
| Toolchain | Status |
|---|---|
MSVC cl.exe (Windows) |
✅ Primary |
| MinGW (Windows) | ✅ Supported |
| GCC (Linux / macOS) | 🔧 Planned |
LuaJIT is built automatically from source by CMake — no separate installation needed.
Prerequisites:
- CMake 3.30+
- A supported C/C++ compiler (see above)
- Internet access for FetchContent (kwxFFI and wxWidgets are fetched automatically)
# Configure and build (Windows, MSVC)
cmake --preset windows-msvc
cmake --build build --config Debug
# Run an example
.\build\Debug\kwxlua.exe examples\hello.luaApache License 2.0 — see LICENSE for details.