I built a JSON Schema–to–Luau type converter in Rust and figured others working with Luau might find it useful.
Luau’s type system is not TypeScript, and most existing tools assume Roblox-specific workflows. This one doesn’t. It’s designed for *standard Luau*, so it works anywhere Luau runs — not just inside Roblox projects.
The tool ingests a JSON Schema file and generates Luau type definitions with full handling of the real JSON Schema feature set:
* Full support for objects, arrays, primitives, enums, const
* `$ref`, `definitions`, and `$defs` (never inlined)
* `allOf`, `anyOf`, `oneOf`
* Required/optional property detection
* Constraints preserved as Luau comments (`@minimum`, `@pattern`, etc.)
* Clear errors and reasonably strict validation
* CLI + library API
The converter tries to follow Luau’s actual type semantics rather than pretending it’s TypeScript. Composition becomes real unions/intersections, referenced definitions become exported types, and constraints are kept as comments so they still surface in tooling.
Limitations are documented (tuple schemas, conditional schemas, propertyNames, remote refs, etc.). Number literal enums degrade to `number` because Luau can’t express them.
I built a JSON Schema–to–Luau type converter in Rust and figured others working with Luau might find it useful.
Luau’s type system is not TypeScript, and most existing tools assume Roblox-specific workflows. This one doesn’t. It’s designed for *standard Luau*, so it works anywhere Luau runs — not just inside Roblox projects.
The tool ingests a JSON Schema file and generates Luau type definitions with full handling of the real JSON Schema feature set:
* Full support for objects, arrays, primitives, enums, const * `$ref`, `definitions`, and `$defs` (never inlined) * `allOf`, `anyOf`, `oneOf` * Required/optional property detection * Constraints preserved as Luau comments (`@minimum`, `@pattern`, etc.) * Clear errors and reasonably strict validation * CLI + library API
Example:
```bash json-schema-to-luau schema.json -o types.luau ```
Input:
```json { "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "number", "minimum": 0, "maximum": 120 } }, "required": ["name"] } ```
Output:
```lua export type Root = { --- @minimum 0 --- @maximum 120 age: number?, name: string, } ```
The converter tries to follow Luau’s actual type semantics rather than pretending it’s TypeScript. Composition becomes real unions/intersections, referenced definitions become exported types, and constraints are kept as comments so they still surface in tooling.
Limitations are documented (tuple schemas, conditional schemas, propertyNames, remote refs, etc.). Number literal enums degrade to `number` because Luau can’t express them.
Crate: `cargo add json-schema-to-luau`
CLI: `cargo install json-schema-to-luau`
Repo: [https://github.com/amirfarzamnia/json-schema-to-luau](https://github.com/amirfarzamnia/json-schema-to-luau)
Would love feedback, bug reports, or ideas for making the output cleaner.