Using the Luart syntax extensions
By Samir Tine, published on April 2026
Introduction
Since version 2.2.0, Luart includes a powerful built-in preprocessor that extends the standard Lua syntax with modern features. To enable the preprocessor in a script, you must add the following directive to the very first line of your Lua script:
--! luart-extensions
You can view exactly how the preprocessor translates your extended syntax into standard Lua code. By using the -p option with the LuaRT interpreter, the parsed code will be printed directly to the standard output instead of being executed:
luart.exe -p myscript.lua
String Interpolation
The preprocessor makes string formatting effortless. You can inject variables and expressions directly into double or single-quoted strings using the ${} syntax :
local framework = "LuaRT"
local version = 3
print("Welcome to ${framework} version ${version/2}")
import
Loading modules is simplified with the import keyword, providing a much cleaner alternative to standard require calls. You can even import multiple modules on a single line. Each imported modules are affected to a local variable with the same name :
import ui --> local ui = require "ui"
import net, crypto --> local net = require "net"; local crypto = require "crypto"
-- use the imported modules as usual
local window = ui.Window("My Window", 800, 600)
window:show()
class
Creating Objects is more intuitive with the dedicated class syntax. You can define properties and methods directly inside the class block without needing external table declarations. Inside a class definition, each field is terminated by a newline (no more comma as with tables), and for methods, the self argument is implicit :
class Animal {
name = "Unknown"
function speak()
print(self.name .. " makes a sound.")
end
}
local dog = Animal()
dog.name = "Rex"
dog:speak()
try..catch...end
Handling errors gracefully is now possible with try and catch blocks :
try
local f = io.open("nonexistent.txt", "r")
local content = f:read("*a")
catch err
print("Failed to open file: " .. err)
end
async & await
Luart syntax extensions permits seamless asynchronous code execution. Use async function to define a Task factory : each time a Task factory is called, a new Task with the given function is started.
-- Declares a Task factory
async function fetch_data()
-- mimics fetching data for 2sec
sleep(2000)
return "Data loaded successfully"
end
-- Start a new task using fetch_data
local task1 = fetch_data()
-- Start a new task using fetch_data
local task2 = fetch_data()
waitall()
The await syntax extensions is used to pause current execution until the followed task (or function wrapped as a launched Task) completes :
-- Declares a Task factory
async function fetch_data()
-- mimics fetching data for 2sec
sleep(2000)
return "Data loaded successfully"
end
-- Start a new task using fetch_data
local task1 = fetch_data()
local result = await task1
print(result)
The await syntax expects a function or a Task, so the previous example can be simplifed :
-- Declares a Task factory
async function fetch_data()
-- mimics fetching data for 2sec
sleep(2000)
return "Data loaded successfully"
end
print(await fetch_data())
As you can see, Luart preprocessor is a simple way to extend Lua syntax while still providing full compability with standard Lua scripts (if not used). You are now ready to write cleaner, more modern Lua code !