| Crates.io | tsuki |
| lib.rs | tsuki |
| version | 0.4.5 |
| created_at | 2025-08-12 08:45:09.287632+00 |
| updated_at | 2026-01-18 07:43:37.888963+00 |
| description | Lua 5.4 ported to Rust |
| homepage | |
| repository | https://github.com/ultimaweapon/tsuki |
| max_upload_size | |
| id | 1791700 |
| size | 1,156,963 |
Tsuki is a port of Lua 5.4 to Rust, not binding. This mean all code are Rust and can be using without C compiler. The initial works was done by C2Rust. Note that this port was done without compatibility with previous Lua version. You can see a list of the differences here.
[!WARNING] Tsuki currently in a pre-1.0 so prepare for a lot of breaking changes!
The VM to run Lua code is fully working almost exactly as vanilla Lua (see some of differences below). Some functions on Lua standard library are still missing.
[!IMPORTANT] All types in Tsuki does not implement
SendandSyncand no plan to support this at the moment.
All public API of Tsuki should provide 100% safety as long as you don't use unsafe API incorrectly.
However, Tsuki was not designed to run untrusted Lua script. Although you can limit what Lua script can do by not expose a function to it but there is no way to limit amount of memory or execution time used by Lua script. The meaning of this is Lua script can cause a panic due to out of memory or never return the control back to Rust with infinite loop. It is also possible for Lua script to cause stack overflow on Rust.
Tsuki is slower than Lua about 40% on Linux, 22% on macOS and faster than Lua about 6% on Windows. The only possibility for Tsuki to be faster than Lua with computed goto is JIT since computed goto does not available on Rust.
A call to async function without any suspend on Tsuki is faster than mlua about 2.8x. For 1 suspend Tsuki it faster about 2.4x. For 8 suspend Tsuki is faster about 1.9x.
Result instead of a long jump.core::any::Any as Lua userdata and can be created without the need to define its metatable.core::any::TypeId instead of a string.@).__close metamethod always nil.__gc metamethod is not supported.__name metavalue must be UTF-8 string.__tostring metamethod must return a UTF-8 string.libc has been completely removed)._VERSION, collectgarbage, dofile, loadfile, warn, xpcall, string.dump and debug library.assert accept only a UTF-8 string.coroutine.isyieldable does not accept any arguments.error:
load:
nil or "t".pcall can produce up to 4 results on error and the message does not have a prefix.
coroutine.resume can produce up to 4 results on error the same as pcall.string.format requires format string to be UTF-8.
a, A, e, E, g and G format is not supported.q format requires string value to be UTF-8 and will use decimal notation instead of hexadecimal exponent notation for float.string.find and string.gsub does not support class z.string.pack, string.packsize and string.unpack requires UTF-8 string for format string and format error always argument error.string.unpack always report data error as argument error.LUA_PATH and LUA_PATH_5_4 is ignored.LUA_NOENV in registry is ignored.YieldFp has been added to Value.Float methods has been removed.BadInst has been removed.ChunkInfo was replaced with String.Context::push_from_index and Context::push_from_index_with_int has been replaced with Thread::index.Str::as_str has been renamed to Str::as_utf8.Arg::as_int has additional parameter.Str, Table, LuaFn and UserData no longer implement Unpin.DynamicInputs::push_num has been renamed to DynamicInputs::push_float.DynamicInputs::push_fp now accept Fp instead of function pointer.pcall now produce up to 4 results on error and the message does not have a prefix.string.format now implemented in Rust with some breaking changes.string.rep now have the same result limit as Lua.This requires too much changes to the language so the answer is no. See #16 for more details.
Same as Lua, which is MIT.