4 stable releases

Uses new Rust 2024

new 1.1.1 Mar 2, 2026
1.1.0 Mar 1, 2026
1.0.1 Dec 12, 2025
1.0.0 Dec 11, 2025

#131 in Games

MPL-2.0 license

4MB
15K SLoC

Lua 13K SLoC // 0.0% comments Rust 2K SLoC // 0.0% comments Python 17 SLoC Just 13 SLoC

Contains (ELF exe/lib, 21MB) conformance_test_runner

protoc-gen-luau generates strictly typed Luau files from Protobuf files.

To use, clone the repo and run cargo install. When you run protoc, add --luau_out=path/to/protos. For example, to export protos in protos/ to src/LuauProtos/...

protoc -Iprotos --luau_out=src/LuauProtos

Options

  • Add --luau_opt=roblox_imports=true to indicate you are in a Roblox environment. This currently replaces requires from string requires to instance based requires. I'm not actually sure this is necessary anymore though.

  • --luau_opt=field_name_case=snake|camel — Control Luau field names casing. If no option is passed, the default behavior is to keep the field name as written in the .proto file.

API

Messages

Suppose we have the following message:

message Pair {
	double x = 1;
	double y = 2;
}

The exported script will have the following:

  • Exported type Pair representing the Pair class
  • A Pair class with:
    • Pair.new(partialFields): Pair
      • partialFields in this case would be { x: number?, y: number? }. Anything not specified will be defaulted as per Protobuf's rules.
    • Pair:encode(): buffer
      • Returns a buffer representing the serialized Protobuf.
    • Pair.decode(input: buffer): Pair
      • Deserializes a serialized Protobuf.
    • Pair:jsonEncode(): { [string]: any }
      • Returns a JSON encoded representation of the message as per Protobuf's rules.
    • Pair.jsonDecode(input: { [string]: any }): Pair
      • Deserializes a JSON encoded representation of the message as per Protobuf's rules.
    • Pair.descriptor: proto.Descriptor
      • A runtime representation of what the type is--just a struct with { name: string, fullName: string }.

Enums

If we have the following:

enum Kind {
	A = 0,
	B = 1,
	C = 2,
}

The exported script will export a type Kind that is a union string of all the options, as well as number for when it is unspecified. In this case: "A" | "B" | "C" | number

Any

Any is supported, though these docs are not ready yet.

Dependencies

~18–31MB
~422K SLoC