| Crates.io | json-schema-to-luau |
| lib.rs | json-schema-to-luau |
| version | 1.0.3 |
| created_at | 2025-11-14 01:11:05.893519+00 |
| updated_at | 2025-12-13 23:32:30.5512+00 |
| description | Convert JSON Schema to Luau type definitions with full support for constraints and advanced schema features. |
| homepage | |
| repository | https://github.com/amirfarzamnia/json-schema-to-luau |
| max_upload_size | |
| id | 1932111 |
| size | 91,444 |
Convert JSON Schema to Luau type definitions with full support for constraints and advanced schema features.
$ref, definitions, and $defsallOf, anyOf, oneOf)You can install json-schema-to-luau via Cargo or download a pre-built binary from GitHub Releases.
To use as a Rust library in your project:
cargo add json-schema-to-luau
To install the command-line interface globally:
cargo install json-schema-to-luau
Pre-compiled binaries for various platforms (Linux, macOS, Windows) are available on the GitHub Releases page. This is the fastest way to get the CLI without needing a Rust toolchain.
# Convert a file and output to another file
json-schema-to-luau schema.json -o types.luau
# Read schema from standard input
cat schema.json | json-schema-to-luau - -o types.luau
# Specify a custom type name (defaults to 'Root')
json-schema-to-luau schema.json --type-name MyCustomType
use json_schema_to_luau::convert_schema;
fn main() {
let json_schema = r#"{
"type": "object",
"properties": {
"name": { "type": "string" },
"age": {
"type": "number",
"minimum": 0,
"maximum": 120
}
},
"required": ["name"]
}"#;
let luau_types = convert_schema(json_schema).unwrap();
println!("{}", luau_types);
}
Output:
export type Root = {
--- @minimum 0
--- @maximum 120
age: number?,
name: string,
}
The converter maps JSON Schema concepts to the closest viable Luau types. This is crucial as Luau is not TypeScript and has different type system limitations.
| JSON Schema | Luau Output | Notes |
|---|---|---|
"string" |
string |
|
"number", "integer" |
number |
|
"boolean" |
boolean |
|
"null" |
nil |
Often combined: string | nil |
| enum (strings) | "a" | "b" |
Uses union of literal strings |
| enum (numbers) | number |
Luau cannot represent numeric literal types |
| JSON Schema | Luau Output | Description |
|---|---|---|
array |
{ T } |
General array type |
| object map | { [string]: T } |
Objects with additionalProperties or no properties |
anyOf / oneOf |
union (A | B) |
oneOf exclusivity cannot be enforced in Luau |
allOf |
intersection (A & B) or merged object |
Intersection for standalone allOf, otherwise merged into parent |
$ref, $defs |
export type Name = ... |
Always exports named types; never inlines |
anyOf / oneOf (Union)Both are converted to a Luau union type, as Luau does not enforce the exclusivity of oneOf.
export type T = A | B
allOf (Intersection / Merging)allOf members are merged into the parent object type.export type T = A & B.export type Root = {
--- @minimum 0
--- @maximum 100
age: number?,
name: string,
}
--- @minItems 1
--- @maxItems 10
export type Root = { string }
export type Root = "red" | "green" | "blue"
$ref / $defs)export type Root = {
person: Person?,
}
export type Person = {
age: number?,
name: string?,
}
Note: Referenced types like Person are always exported as named types.
Luau has a simpler type system than JSON Schema. The following features degrade gracefully (i.e., they are ignored or simplified):
items: [A, B, C]) → Not supported.if / then / else) → Ignored.dependencies, dependentSchemas, dependentRequired) → Ignored.patternProperties, propertyNames) → Ignored/Simplified.$ref resolution → Only local fragments (#/...) are supported.number.number?”Luau does not support numeric literal types (e.g., 1 | 2 | 3). Numeric enums from JSON Schema must degrade to the base type number.
{ [string]: any }?”This typically happens when the schema is an object that allows arbitrary properties but does not explicitly declare any of its own (properties is absent or empty, and additionalProperties is the default true).
Only types resolved via a $ref to a root-level definition (#/definitions/Name or #/$defs/Name) are exported as named types. All other complex types (like nested objects or arrays) are intentionally inlined for conciseness.
convert_schema(&str) -> Result<String>The simplest function. Parses the JSON Schema string and returns the resulting Luau type definitions.
SchemaConverterFor advanced usage (e.g., reusing definitions across multiple calls):
let mut converter = SchemaConverter::new();
let luau = converter.convert(&schema)?;
let luau = converter.convert_with_name(&schema, "MyType")?;
$ref resolution is single-pass and only supports local fragments.MIT License