{"id":13496645,"url":"https://github.com/mlua-rs/mlua","last_synced_at":"2026-04-22T01:05:40.467Z","repository":{"id":37445143,"uuid":"224943004","full_name":"mlua-rs/mlua","owner":"mlua-rs","description":"High level Lua 5.5/5.4/5.3/5.2/5.1 (including LuaJIT) and Luau bindings to Rust with async/await support","archived":false,"fork":false,"pushed_at":"2026-04-18T12:28:12.000Z","size":4124,"stargazers_count":2663,"open_issues_count":62,"forks_count":199,"subscribers_count":18,"default_branch":"main","last_synced_at":"2026-04-18T14:25:29.137Z","etag":null,"topics":["async","asynchronous","lua","luajit","luau","rust","rust-bindings","scripting","wasm"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mlua-rs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"khvzak"}},"created_at":"2019-11-30T01:20:27.000Z","updated_at":"2026-04-18T12:28:16.000Z","dependencies_parsed_at":"2023-02-09T08:31:23.838Z","dependency_job_id":"dfcd4493-cb83-4611-8295-e8b60d7f4a1e","html_url":"https://github.com/mlua-rs/mlua","commit_stats":{"total_commits":1403,"total_committers":32,"mean_commits":43.84375,"dds":"0.31860299358517463","last_synced_commit":"3787ff9e8c907843b1dfe920e269d188b637f9f3"},"previous_names":["khvzak/mlua"],"tags_count":81,"template":false,"template_full_name":null,"purl":"pkg:github/mlua-rs/mlua","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlua-rs%2Fmlua","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlua-rs%2Fmlua/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlua-rs%2Fmlua/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlua-rs%2Fmlua/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mlua-rs","download_url":"https://codeload.github.com/mlua-rs/mlua/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlua-rs%2Fmlua/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32116514,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-22T00:31:26.853Z","status":"ssl_error","status_checked_at":"2026-04-22T00:30:22.894Z","response_time":128,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["async","asynchronous","lua","luajit","luau","rust","rust-bindings","scripting","wasm"],"created_at":"2024-07-31T19:01:54.294Z","updated_at":"2026-04-22T01:05:40.461Z","avatar_url":"https://github.com/mlua-rs.png","language":"Rust","readme":"# mlua\n[![Build Status]][github-actions] [![Latest Version]][crates.io] [![API Documentation]][docs.rs] [![Coverage Status]][codecov.io] ![MSRV]\n\n[Build Status]: https://github.com/mlua-rs/mlua/workflows/CI/badge.svg\n[github-actions]: https://github.com/mlua-rs/mlua/actions\n[Latest Version]: https://img.shields.io/crates/v/mlua.svg\n[crates.io]: https://crates.io/crates/mlua\n[API Documentation]: https://docs.rs/mlua/badge.svg\n[docs.rs]: https://docs.rs/mlua\n[Coverage Status]: https://codecov.io/gh/mlua-rs/mlua/branch/main/graph/badge.svg?token=99339FS1CG\n[codecov.io]: https://codecov.io/gh/mlua-rs/mlua\n[MSRV]: https://img.shields.io/badge/rust-1.79+-brightgreen.svg?\u0026logo=rust\n\n[Guided Tour] | [Benchmarks] | [FAQ]\n\n[Guided Tour]: examples/guided_tour.rs\n[Benchmarks]: https://github.com/khvzak/script-bench-rs\n[FAQ]: FAQ.md\n\n## The main branch is the development version of `mlua`. Please see the [v0.11](https://github.com/mlua-rs/mlua/tree/v0.11) branch for the stable versions of `mlua`.\n\n`mlua` is a set of bindings to the [Lua](https://www.lua.org) programming language for Rust with a goal of providing a\n_safe_ (as much as possible), high level, easy to use, practical and flexible API.\n\nStarted as an `rlua` fork, `mlua` supports Lua 5.5, 5.4, 5.3, 5.2, 5.1 (including LuaJIT) and [Luau] and allows writing native Lua modules in Rust as well as using Lua in a standalone mode.\n\n`mlua` is tested on Windows/macOS/Linux including module mode in [GitHub Actions] on `x86_64` platforms and cross-compilation to `aarch64` (other targets are also supported).\n\nWebAssembly (WASM) is supported through the `wasm32-unknown-emscripten` target for all Lua/Luau versions excluding JIT.\n\n[GitHub Actions]: https://github.com/mlua-rs/mlua/actions\n[Luau]: https://luau.org\n\n## Usage\n\n### Feature flags\n\n`mlua` uses feature flags to reduce the number of dependencies and compiled code, and allow choosing only the required set of features.\nBelow is a list of the available feature flags. By default `mlua` does not enable any features.\n\n* `lua55`: enable Lua [5.5] support\n* `lua54`: enable Lua [5.4] support\n* `lua53`: enable Lua [5.3] support\n* `lua52`: enable Lua [5.2] support\n* `lua51`: enable Lua [5.1] support\n* `luajit`: enable [LuaJIT] support\n* `luajit52`: enable [LuaJIT] support with partial compatibility with Lua 5.2\n* `luau`: enable [Luau] support (auto vendored mode)\n* `luau-jit`: enable [Luau] support with JIT backend.\n* `luau-vector4`: enable [Luau] support with 4-dimensional vector.\n* `vendored`: build static Lua(JIT) libraries from sources during `mlua` compilation using [lua-src] or [luajit-src]\n* `module`: enable module mode (building loadable `cdylib` library for Lua)\n* `async`: enable async/await support (any executor can be used, eg. [tokio] or [async-std])\n* `send`: make `mlua::Lua: Send + Sync` (adds [`Send`] requirement to `mlua::Function` and `mlua::UserData`)\n* `error-send`: make `mlua:Error: Send + Sync`\n* `serde`: add serialization and deserialization support to `mlua` types using [serde]\n* `macros`: enable procedural macros (such as `chunk!`)\n* `anyhow`: enable `anyhow::Error` conversion into Lua\n* `userdata-wrappers`: opt into `impl UserData` for `Rc\u003cT\u003e`/`Arc\u003cT\u003e`/`Rc\u003cRefCell\u003cT\u003e\u003e`/`Arc\u003cMutex\u003cT\u003e\u003e` where `T: UserData`\n\n[5.5]: https://www.lua.org/manual/5.5/manual.html\n[5.4]: https://www.lua.org/manual/5.4/manual.html\n[5.3]: https://www.lua.org/manual/5.3/manual.html\n[5.2]: https://www.lua.org/manual/5.2/manual.html\n[5.1]: https://www.lua.org/manual/5.1/manual.html\n[LuaJIT]: https://luajit.org/\n[Luau]: https://github.com/luau-lang/luau\n[lua-src]: https://github.com/mlua-rs/lua-src-rs\n[luajit-src]: https://github.com/mlua-rs/luajit-src-rs\n[tokio]: https://github.com/tokio-rs/tokio\n[async-std]: https://github.com/async-rs/async-std\n[`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html\n[serde]: https://github.com/serde-rs/serde\n\n### Async/await support\n\n`mlua` supports async/await for all Lua versions including Luau.\n\nThis works using Lua [coroutines](https://www.lua.org/manual/5.3/manual.html#2.6) and requires running [Thread](https://docs.rs/mlua/latest/mlua/struct.Thread.html) along with enabling `feature = \"async\"` in `Cargo.toml`.\n\n**Examples**:\n- [HTTP Client](examples/async_http_client.rs)\n- [HTTP Client (json)](examples/async_http_reqwest.rs)\n- [HTTP Server](examples/async_http_server.rs)\n- [TCP Server](examples/async_tcp_server.rs)\n\n\n**shell command examples**:\n```shell\n# async http client (hyper)\ncargo run --example async_http_client --features=lua54,async,macros\n\n# async http client (reqwest)\ncargo run --example async_http_reqwest --features=lua54,async,macros,serde\n\n# async http server\ncargo run --example async_http_server --features=lua54,async,macros,send\ncurl -v http://localhost:3000\n```\n\n### Serde support\n\nWith the `serde` feature flag enabled, `mlua` allows you to serialize/deserialize any type that implements [`serde::Serialize`] and [`serde::Deserialize`] into/from [`mlua::Value`]. In addition, `mlua` provides the [`serde::Serialize`] trait implementation for `mlua::Value` (including `UserData` support).\n\n[Example](examples/serde.rs)\n\n[`serde::Serialize`]: https://docs.serde.rs/serde/ser/trait.Serialize.html\n[`serde::Deserialize`]: https://docs.serde.rs/serde/de/trait.Deserialize.html\n[`mlua::Value`]: https://docs.rs/mlua/latest/mlua/enum.Value.html\n\n### Compiling\n\nYou have to enable one of the features: `lua54`, `lua53`, `lua52`, `lua51`, `luajit(52)` or `luau`, according to the chosen Lua version.\n\nBy default `mlua` uses `pkg-config` to find Lua includes and libraries for the chosen Lua version.\nIn most cases it works as desired, although sometimes it may be preferable to use a custom Lua library.\nTo achieve this, mlua supports the `LUA_LIB`, `LUA_LIB_NAME` and `LUA_LINK` environment variables.\n`LUA_LINK` is optional and may be `dylib` (a dynamic library) or `static` (a static library, `.a` archive).\n\nAn example of how to use them:\n``` sh\nmy_project $ LUA_LIB=$HOME/tmp/lua-5.2.4/src LUA_LIB_NAME=lua LUA_LINK=static cargo build\n```\n\n`mlua` also supports vendored Lua/LuaJIT using the auxiliary crates [lua-src](https://crates.io/crates/lua-src) and\n[luajit-src](https://crates.io/crates/luajit-src).\nJust enable the `vendored` feature and cargo will automatically build and link the specified Lua/LuaJIT version. This is the easiest way to get started with `mlua`.\n\n### Standalone mode\nIn standalone mode, `mlua` allows adding scripting support to your application with a properly configured Lua runtime to ensure safety and soundness.\n\nAdd to `Cargo.toml`:\n\n``` toml\n[dependencies]\nmlua = { version = \"0.11\", features = [\"lua54\", \"vendored\"] }\n```\n\n`main.rs`\n\n``` rust\nuse mlua::prelude::*;\n\nfn main() -\u003e LuaResult\u003c()\u003e {\n    let lua = Lua::new();\n\n    let map_table = lua.create_table()?;\n    map_table.set(1, \"one\")?;\n    map_table.set(\"two\", 2)?;\n\n    lua.globals().set(\"map_table\", map_table)?;\n\n    lua.load(\"for k,v in pairs(map_table) do print(k,v) end\").exec()?;\n\n    Ok(())\n}\n```\n\n### Module mode\nIn module mode, `mlua` allows creating a compiled Lua module that can be loaded from Lua code using [`require`](https://www.lua.org/manual/5.4/manual.html#pdf-require). In this case `mlua` uses an external Lua runtime which could lead to potential unsafety due to the unpredictability of the Lua environment and usage of libraries such as [`debug`](https://www.lua.org/manual/5.4/manual.html#6.10).\n\n[Example](examples/module)\n\nAdd to `Cargo.toml`:\n\n``` toml\n[lib]\ncrate-type = [\"cdylib\"]\n\n[dependencies]\nmlua = { version = \"0.11\", features = [\"lua54\", \"module\"] }\n```\n\n`lib.rs`:\n\n``` rust\nuse mlua::prelude::*;\n\nfn hello(_: \u0026Lua, name: String) -\u003e LuaResult\u003c()\u003e {\n    println!(\"hello, {}!\", name);\n    Ok(())\n}\n\n#[mlua::lua_module]\nfn my_module(lua: \u0026Lua) -\u003e LuaResult\u003cLuaTable\u003e {\n    let exports = lua.create_table()?;\n    exports.set(\"hello\", lua.create_function(hello)?)?;\n    Ok(exports)\n}\n```\n\nAnd then (**macOS** example):\n\n``` sh\n$ cargo rustc -- -C link-arg=-undefined -C link-arg=dynamic_lookup\n$ ln -s ./target/debug/libmy_module.dylib ./my_module.so\n$ lua5.4 -e 'require(\"my_module\").hello(\"world\")'\nhello, world!\n```\n\nOn macOS, you need to set additional linker arguments. One option is to compile with `cargo rustc --release -- -C link-arg=-undefined -C link-arg=dynamic_lookup`, the other is to create a `.cargo/config.toml` with the following content:\n``` toml\n[target.x86_64-apple-darwin]\nrustflags = [\n  \"-C\", \"link-arg=-undefined\",\n  \"-C\", \"link-arg=dynamic_lookup\",\n]\n\n[target.aarch64-apple-darwin]\nrustflags = [\n  \"-C\", \"link-arg=-undefined\",\n  \"-C\", \"link-arg=dynamic_lookup\",\n]\n```\nOn Linux you can build modules normally with `cargo build --release`.\n\nOn Windows the target module will be linked with the `lua5x.dll` library (depending on your feature flags).\nYour main application should provide this library.\n\nModule builds don't require Lua binaries or headers to be installed on the system.\n\n### Publishing to luarocks.org\n\nThere is a LuaRocks build backend for mlua modules: [`luarocks-build-rust-mlua`].\n\nModules written in Rust and published to luarocks:\n- [`decasify`](https://github.com/alerque/decasify)\n- [`lua-ryaml`](https://github.com/khvzak/lua-ryaml)\n- [`tiktoken_core`](https://github.com/gptlang/lua-tiktoken)\n- [`toml-edit`](https://github.com/vhyrro/toml-edit.lua)\n- [`typst-lua`](https://github.com/rousbound/typst-lua)\n\n[`luarocks-build-rust-mlua`]: https://luarocks.org/modules/khvzak/luarocks-build-rust-mlua\n\n## Safety\n\nOne of `mlua`'s goals is to provide a *safe* API between Rust and Lua.\nEvery place where the Lua C API may trigger an error longjmp is protected by `lua_pcall`,\nand the user of the library is protected from directly interacting with unsafe things like the Lua stack.\nThere is overhead associated with this safety.\n\nUnfortunately, `mlua` does not provide absolute safety even without using `unsafe` .\nThis library contains a huge amount of unsafe code. There are almost certainly bugs still lurking in this library!\nIt is surprisingly, fiendishly difficult to use the Lua C API without the potential for unsafety.\n\n## Panic handling\n\n`mlua` wraps panics that are generated inside Rust callbacks in a regular Lua error. Panics can then be\nresumed by returning or propagating the Lua error to Rust code.\n\nFor example:\n``` rust\nlet lua = Lua::new();\nlet f = lua.create_function(|_, ()| -\u003e LuaResult\u003c()\u003e {\n    panic!(\"test panic\");\n})?;\nlua.globals().set(\"rust_func\", f)?;\n\nlet _ = lua.load(r#\"\n    local status, err = pcall(rust_func)\n    print(err) -- prints: test panic\n    error(err) -- propagate panic\n\"#).exec();\n\nunreachable!()\n```\n\nOptionally, `mlua` can disable Rust panic catching in Lua via `pcall`/`xpcall` and automatically resume\nthem across the Lua API boundary. This is controlled via `LuaOptions` and done by wrapping the Lua `pcall`/`xpcall`\nfunctions to prevent catching errors that are wrapped Rust panics.\n\n`mlua` should also be panic safe in another way as well, which is that any `Lua` instances or handles\nremain usable after a user generated panic, and such panics should not break internal invariants or\nleak Lua stack space. This is mostly important to safely use `mlua` types in Drop impls, as you should not be\nusing panics for general error handling.\n\nBelow is a list of `mlua` behaviors that should be considered bugs.\nIf you encounter them, a bug report would be very welcome:\n\n  + If you can cause UB with `mlua` without typing the word \"unsafe\", this is a bug.\n\n  + If your program panics with a message that contains the string \"mlua internal error\", this is a bug.\n\n  + Lua C API errors are handled by longjmp. All instances where the Lua C API would otherwise longjmp over calling stack frames should be guarded against, except in internal callbacks where this is intentional. If you detect that `mlua` is triggering a longjmp over your Rust stack frames, this is a bug!\n\n  + If you detect that, after catching a panic or during a Drop triggered from a panic, a `Lua` or handle method is triggering other bugs or there is a Lua stack space leak, this is a bug. `mlua` instances are supposed to remain fully usable in the face of user generated panics. This guarantee does not extend to panics marked with \"mlua internal error\" simply because that is already indicative of a separate bug.\n\n## Sandboxing\n\nPlease check the [Luau Sandboxing] page if you are interested in running untrusted Lua scripts in a controlled environment.\n\n`mlua` provides the `Lua::sandbox` method for enabling sandbox mode (Luau only).\n\n[Luau Sandboxing]: https://luau.org/sandbox\n\n## License\n\nThis project is licensed under the [MIT license](LICENSE).\n","funding_links":["https://github.com/sponsors/khvzak"],"categories":["Rust","Development tools"],"sub_categories":["FFI"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmlua-rs%2Fmlua","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmlua-rs%2Fmlua","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmlua-rs%2Fmlua/lists"}