{"id":30273158,"url":"https://github.com/mxpv/luaz","last_synced_at":"2025-08-16T06:40:18.825Z","repository":{"id":308042829,"uuid":"1027375957","full_name":"mxpv/luaz","owner":"mxpv","description":" Zero-cost Luau wrapper for Zig","archived":false,"fork":false,"pushed_at":"2025-08-10T20:20:44.000Z","size":898,"stargazers_count":18,"open_issues_count":4,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-10T21:15:06.493Z","etag":null,"topics":["lua","luau","zig","zig-lib","zig-library","zig-package"],"latest_commit_sha":null,"homepage":"https://mxpv.github.io/luaz/","language":"Zig","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mxpv.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-27T22:30:52.000Z","updated_at":"2025-08-10T20:20:48.000Z","dependencies_parsed_at":"2025-08-03T20:41:55.498Z","dependency_job_id":"6aa8c487-6cd6-490c-b184-36dcc79a4fdd","html_url":"https://github.com/mxpv/luaz","commit_stats":null,"previous_names":["mxpv/luaz"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/mxpv/luaz","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mxpv%2Fluaz","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mxpv%2Fluaz/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mxpv%2Fluaz/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mxpv%2Fluaz/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mxpv","download_url":"https://codeload.github.com/mxpv/luaz/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mxpv%2Fluaz/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270678545,"owners_count":24626919,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-16T02:00:11.002Z","response_time":91,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["lua","luau","zig","zig-lib","zig-library","zig-package"],"created_at":"2025-08-16T06:40:14.906Z","updated_at":"2025-08-16T06:40:18.771Z","avatar_url":"https://github.com/mxpv.png","language":"Zig","readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/logo.png\" /\u003e\n\u003c/p\u003e\n\n# luaz\n\n[![CI](https://github.com/mxpv/luaz/actions/workflows/ci.yml/badge.svg)](https://github.com/mxpv/luaz/actions/workflows/ci.yml)\n[![Docs](https://github.com/mxpv/luaz/actions/workflows/docs.yml/badge.svg)](https://github.com/mxpv/luaz/actions/workflows/docs.yml)\n[![GitHub License](https://img.shields.io/github/license/mxpv/luaz)](./LICENSE)\n[![codecov](https://codecov.io/gh/mxpv/luaz/branch/main/graph/badge.svg?token=GUTOF5TGFQ)](https://codecov.io/gh/mxpv/luaz)\n\n`luaz` is a zero-cost wrapper library for [`Luau`](https://github.com/luau-lang/luau).\nUnlike other libraries, it focuses specifically on `Luau`, providing idiomatic `Zig` bindings that leverage Luau's [unique features](https://luau.org/why)\nand [performance](https://luau.org/performance) characteristics.\n\n## ✨ Features\n\n- Minimal yet flexible zero-cost [API](#basic-usage)\n- Bidirectional [function calls](#function-calls) between `Zig` and `Lua`\n  - Closures support with upvalue capture\n  - Variadic arguments support\n- Complete Lua API coverage:\n  - Support for references, tables, and functions\n  - Full coroutine and thread support\n  - Comprehensive garbage collection APIs\n  - A fully featured debugger APIs\n- First-class [userdata support](#userdata-integration) including metamethods\n- Luau-specific features:\n  - Vector type support\n  - Buffer type support for binary data manipulation\n  - [StrBuf support](#string-buffer-strbuf)\n  - Sandboxing APIs for secure execution and improved performance\n  - Built-in Luau tools provided out of the box:\n    - [`luau-compile`](#compiler) - Compile Lua source to optimized bytecode\n    - [`luau-analyze`](#analyzer) - Type checking and linting for Luau code\n  - Native code generation support for improved performance on supported platforms\n- Excellent [test coverage](https://app.codecov.io/gh/mxpv/luaz) and API [documentation](https://mxpv.github.io/luaz/#luaz)\n\n## 📚 Documentation\n\nFull API documentation is available at: https://mxpv.github.io/luaz/#luaz\n\nThe documentation is automatically updated on every change to the `main` branch.\n\n- [Documentation](https://mxpv.github.io/luaz/#luaz.lib)\n  + [High level Lua interface](https://mxpv.github.io/luaz/#luaz.lib.Lua)\n    - [Table](https://mxpv.github.io/luaz/#luaz.Table)\n    - [Function](https://mxpv.github.io/luaz/#luaz.Function)\n    - [StrBuf](https://mxpv.github.io/luaz/#luaz.StrBuf)\n    - [Buffer](https://mxpv.github.io/luaz/#luaz.Buffer)\n  + [Low level State wrapper](https://mxpv.github.io/luaz/#luaz.State)\n  + [GC API](https://mxpv.github.io/luaz/#luaz.GC)\n  + [Debugger API](https://mxpv.github.io/luaz/#luaz.Debug)\n  + [Compiler](https://mxpv.github.io/luaz/#luaz.Compiler)\n\n\u003e [!TIP]\n\u003e For a comprehensive overview of all features, see the [guided tour example](examples/guided_tour.zig) which can be run with `zig build guided-tour`.\n\n### Basic Usage\n\nThe following example demonstrates some basic use cases.\n\n- `Lua` takes optional Zig allocator.\n- Global table `_G` is available via `globals()` table.\n- `eval` is a helper function that compiles Lua code to Luau bytecode and executes it.\n- `set` and `get` are used to pass and retrieve data.\n\n```zig\nconst std = @import(\"std\");\nconst luaz = @import(\"luaz\");\nconst assert = std.debug.assert;\n\npub fn main() !void {\n    var gpa = std.heap.GeneralPurposeAllocator(.{}){};\n    defer _ = gpa.deinit();\n\n    var lua = try Lua.init(\u0026gpa.allocator); // Create Lua state with custom allocator\n    defer lua.deinit(); // Clean up Lua state\n\n    // Set a global variable\n    try lua.globals().set(\"greeting\", \"Hello from Zig!\");\n\n    // Get and verify the global variable\n    const value = try lua.globals().get(\"greeting\", []const u8);\n    assert(std.mem.eql(u8, value.?, \"Hello from Zig!\"));\n\n    // Evaluate Lua code and get result\n    const result = try lua.eval(\"return 2 + 3 * 4\", .{}, i32);\n    assert(result.ok.? == 14);\n}\n```\n\n\u003e [!NOTE]\n\u003e Ideally, the bundled  `luau-compile` tool should be used to precompile Lua scripts offline.\n\n### Struct and Array Tables\n\nZig structs and arrays are automatically converted to Lua tables:\n\n```zig\nconst std = @import(\"std\");\nconst luaz = @import(\"luaz\");\n\nconst Point = struct { x: f64, y: f64 };\n\npub fn main() !void {\n    var lua = try Lua.init(null);\n    defer lua.deinit();\n\n    // Struct becomes a Lua table with field names as keys\n    const point = Point{ .x = 10.5, .y = 20.3 };\n    try lua.globals().set(\"point\", point);\n\n    // Array becomes a Lua table with 1-based integer indices\n    const numbers = [_]i32{ 1, 2, 3, 4, 5 };\n    try lua.globals().set(\"numbers\", numbers);\n\n    // Access from Lua\n    const x_result = try lua.eval(\"return point.x\", .{}, f64);\n    const x = x_result.ok.?;          // 10.5\n    const first_result = try lua.eval(\"return numbers[1]\", .{}, i32);\n    const first = first_result.ok.?;   // 1\n    const length_result = try lua.eval(\"return #numbers\", .{}, i32);\n    const length = length_result.ok.?;    // 5\n}\n```\n\n### Function Calls\n\nBoth Lua functions can be called from Zig and Zig functions from Lua with automatic type conversion and argument \nhandling.\n\n```zig\nconst std = @import(\"std\");\nconst luaz = @import(\"luaz\");\nconst assert = std.debug.assert;\n\nfn sum(a: i32, b: i32) i32 {\n    return a + b;\n}\n\npub fn main() !void {\n    var lua = try Lua.init(null); // Use default allocator\n    defer lua.deinit();\n\n    // Register Zig function in Lua\n    try lua.globals().set(\"sum\", sum);\n\n    // Call Zig function from Lua\n    const result1 = try lua.eval(\"return sum(10, 20)\", .{}, i32);\n    assert(result1.ok.? == 30);\n\n    // Define Lua function\n    _ = try lua.eval(\"function multiply(x, y) return x * y end\", .{}, void);\n\n    // Call Lua function from Zig\n    const result2 = try lua.globals().call(\"multiply\", .{6, 7}, i32);\n    assert(result2.ok.? == 42);\n\n    // Closures with captured values\n    const table = lua.createTable(.{});\n    defer table.deinit();\n    \n    fn getGlobal(upv: Lua.Upvalues(*Lua), key: []const u8) !i32 {\n        return try upv.value.globals().get(key, i32) orelse 0;\n    }\n    const lua_ptr = @constCast(\u0026lua);\n    try table.setClosure(\"getGlobal\", lua_ptr, getGlobal);\n    try lua.globals().set(\"funcs\", table);\n    try lua.globals().set(\"myValue\", @as(i32, 123));\n    \n    const result3 = try lua.eval(\"return funcs.getGlobal('myValue')\", .{}, i32);\n    assert(result3.ok.? == 123);\n}\n```\n\n### UserData Integration\n\nluaz has automatic compile-time binding generation for user data. It supports constructors, static and instance \nmethods. If a struct has `deinit`, it'll be automatically invoked on garbage collection.\n\n```zig\nconst std = @import(\"std\");\nconst luaz = @import(\"luaz\");\nconst assert = std.debug.assert;\n\nconst Counter = struct {\n    value: i32,\n\n    pub fn init(initial: i32) Counter {\n        return Counter{ .value = initial };\n    }\n\n    pub fn deinit(self: *Counter) void {\n        std.log.info(\"Counter with value {} being destroyed\", .{self.value});\n    }\n\n    pub fn getMaxValue() i32 {\n        return std.math.maxInt(i32);\n    }\n\n    pub fn increment(self: *Counter, amount: i32) i32 {\n        self.value += amount;\n        return self.value;\n    }\n\n    pub fn getValue(self: *const Counter) i32 {\n        return self.value;\n    }\n\n    // Metamethods for arithmetic operations\n    pub fn __add(self: Counter, other: i32) Counter {\n        return Counter{ .value = self.value + other };\n    }\n\n    pub fn __tostring(self: Counter) []const u8 {\n        return std.fmt.allocPrint(std.heap.page_allocator, \"Counter({})\", .{self.value}) catch \"Counter\";\n    }\n\n    pub fn __len(self: Counter) i32 {\n        return self.value;\n    }\n};\n\npub fn main() !void {\n    var lua = try luaz.Lua.init(null);\n    defer lua.deinit();\n\n    // Register Counter type with Lua\n    try lua.registerUserData(Counter);\n\n    _ = try lua.eval(\n        \\\\local counter = Counter.new(10)     -- Use constructor\n        \\\\assert(counter:increment(5) == 15)  -- Call instance method\n        \\\\assert(counter:getValue() == 15)   -- Get current value\n        \\\\\n        \\\\local max = Counter.getMaxValue()   -- Call static method\n        \\\\assert(max == 2147483647)           -- Max i32 value\n        \\\\\n        \\\\-- Metamethods in action\n        \\\\local new_counter = counter + 5     -- Uses __add metamethod\n        \\\\assert(new_counter:getValue() == 20)\n        \\\\assert(#counter == 15)              -- Uses __len metamethod\n        \\\\print(tostring(counter))            -- Uses __tostring metamethod\n    , .{}, void);\n}\n```\n\n### String Buffer (StrBuf)\n\nEfficient string building using Luau's StrBuf API with automatic memory management.\n\n```zig\nfn buildGreeting(upv: Lua.Upvalues(*Lua), name: []const u8, age: i32) !Lua.StrBuf {\n    var buf: Lua.StrBuf = undefined;\n    buf.init(upv.value);\n    buf.addString(\"Hello, \");\n    buf.addLString(name);\n    buf.addString(\"! You are \");\n    try buf.add(age);\n    buf.addString(\" years old.\");\n    return buf;\n}\n\n// Register and call from Lua\ntry lua.globals().setClosure(\"buildGreeting\", \u0026lua, buildGreeting);\nconst result = try lua.eval(\"return buildGreeting('Alice', 25)\", .{}, []const u8);\nconst greeting = result.ok.?;\n```\n\n\u003e [!WARNING]\n\u003e This library is still evolving and the API is not stable. Backward incompatible changes may be introduced up until the 1.0 release. Consider pinning to a specific commit or tag if you need stability.\n\n## 🔧 Build Configuration\n\n### Vector Size\nBy default, luaz is built with 4-component vectors. To customize:\n```bash\nzig build -Dvector-size=3  # Build with 3-component vectors\n```\n\n## 🛠️ Using Luau Tools\n\nThe build system provides prebuilt Luau tools that can be invoked directly:\n\n### Analyzer\n```bash\n$ zig build luau-analyze -- --help\nUsage: /Users/.../luaz/.zig-cache/o/.../luau-analyze [--mode] [options] [file list]\n\nAvailable modes:\n  omitted: typecheck and lint input files\n  --annotate: typecheck input files and output source with type annotations\n\nAvailable options:\n  --formatter=plain: report analysis errors in Luacheck-compatible format\n  --formatter=gnu: report analysis errors in GNU-compatible format\n  --mode=strict: default to strict mode when typechecking\n  --timetrace: record compiler time tracing information into trace.json\n```\n\n### Compiler\n```bash\n$ zig build luau-compile -- --help\nUsage: /Users/.../luaz/.zig-cache/o/.../luau-compile [--mode] [options] [file list]\n\nAvailable modes:\n   binary, text, remarks, codegen\n\nAvailable options:\n  -h, --help: Display this usage message.\n  -O\u003cn\u003e: compile with optimization level n (default 1, n should be between 0 and 2).\n  -g\u003cn\u003e: compile with debug level n (default 1, n should be between 0 and 2).\n  --target=\u003ctarget\u003e: compile code for specific architecture (a64, x64, a64_nf, x64_ms).\n  ...\n```\n\n## 🔗 Related Projects\n\nThese projects served as inspiration and are worth exploring:\n\n- [zig-autolua](https://github.com/daurnimator/zig-autolua) - Automatic Lua bindings for Zig\n- [zoltan](https://github.com/ranciere/zoltan) - Lua bindings for Zig\n- [ziglua](https://github.com/natecraddock/ziglua) - Zig bindings for Lua 5.1, 5.2, 5.3, 5.4, and LuaJIT\n\n## 📄 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n","funding_links":[],"categories":["Zig"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmxpv%2Fluaz","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmxpv%2Fluaz","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmxpv%2Fluaz/lists"}