ezOS provides a comprehensive Lua API for building applications on the T-Deck Plus hardware. This reference documents all available functions, organized by module.
ez.system.gc()Many ezOS APIs are designed for coroutine-based async programming:
local function load_async()
local data = load_module("/scripts/heavy_module.lua") -- Yields while loading
process(data)
end
spawn(load_async)
Functions that yield are noted in their documentation. Don't call yielding functions outside of a coroutine context.
Most functions return nil on error rather than throwing. Check return values:
local file = ez.storage.read_file("/path")
if not file then
print("Failed to read file")
return
end
Display functions use RGB565 format (16-bit color). Use ez.display.rgb(r, g, b) to
convert from 8-bit RGB, or use predefined colors from ez.display.colors:
local red = ez.display.colors.RED
local custom = ez.display.rgb(128, 64, 255)
draw_box()flush() once per frameunload_module() to free memoryez.system.get_lua_memory() to monitor usage328 functions across 16 modules. Click a module to view its documentation.
Audio synthesis and playback via I2S DAC
Publish/subscribe message bus for decoupled communication
Cryptographic primitives for hashing, encryption, and encoding
2D drawing primitives and text rendering for the 320x240 LCD
GPS receiver for location, time, and navigation data
Physical keyboard and trackball input handling
LoRa mesh networking with MeshCore protocol
Low-level LoRa radio configuration and status
Off-screen drawing surface for compositing and overlays
File I/O for internal flash (LittleFS) and SD card
Multi-voice software synth (chip-tune SFX + simple music).
System utilities, timers, memory info, and power management
WiFi connectivity for network access
The message bus provides publish/subscribe communication between components.
Use ez.bus.subscribe() to listen for events and ez.bus.post() to publish them.
local sub_id = ez.bus.subscribe("channel/message", function(data)
print("New message:", data.text)
end)
-- Later, to unsubscribe:
ez.bus.unsubscribe(sub_id)
ez.bus.post("settings/changed", "brightness=200")
ez.bus.post("custom/event", { value = 42, name = "test" })
table {channel, sender, sender_name, text, timestamp, is_self}ez.bus.subscribe("channel/message", function(msg)
print(string.format("[%s] %s: %s",
msg.channel, msg.sender_name, msg.text))
end)
string Format: "channel_name:count"ez.bus.subscribe("channel/unread", function(data)
local channel, count = data:match("(.+):(%d+)")
self:update_badge(channel, tonumber(count))
end)
string Number of nodes as stringez.bus.subscribe("mesh/node_count", function(count)
self.node_count = tonumber(count) or 0
end)
string Message ID that was acknowledgedez.bus.subscribe("message/acked", function(msg_id)
self:mark_delivered(msg_id)
end)
table {from, from_name, text, timestamp, conversation_id}ez.bus.subscribe("message/received", function(msg)
Toast.show("DM from " .. msg.from_name)
end)
string Screen title that was removedez.bus.subscribe("screen/popped", function(title)
print("Left screen: " .. title)
end)
string Screen titleez.bus.subscribe("screen/pushed", function(title)
print("Navigated to: " .. title)
end)
string Format: "old_title>new_title"ez.bus.subscribe("screen/replaced", function(data)
local old, new = data:match("(.+)>(.+)")
print("Replaced " .. old .. " with " .. new)
end)
string Format: "setting_name=value"ez.bus.subscribe("settings/changed", function(data)
local name, value = data:match("(.+)=(.+)")
if name == "brightness" then
print("Brightness changed to: " .. value)
end
end)
string Color scheme nameez.bus.subscribe("theme/colors", function(scheme)
self.bg_color = ThemeManager.colors.background
end)
string Icon pack nameez.bus.subscribe("theme/icons", function(pack)
self:reload_icons()
end)
string Wallpaper name (e.g., "clouds", "mountains", "none")ez.bus.subscribe("theme/wallpaper", function(name)
print("Wallpaper changed to: " .. name)
end)