What is JSON to Crystal Struct Generator?
Crystal is a statically-typed, Ruby-inspired programming language that compiles to native code using LLVM. Its type system distinguishes between value types allocated on the stack (`struct`) and reference types on the heap (`class`), and this generator produces `struct` definitions with `property` declarations — the Crystal idiom for mutable value objects. When you feed in JSON, the generator infers Crystal's specific numeric types: `Int32` for integers, `Float64` for decimals, `Bool` for booleans, `String` for text, and `Nil` for null values. Nested JSON objects become separate struct definitions with PascalCase names, ordered children-first so the Crystal compiler sees the inner type before the outer type that references it. Arrays use Crystal's generic syntax `Array(Type)` rather than the shorthand `Type[]` to avoid ambiguity in struct definitions.
How to Use
- Paste a representative JSON response from your API into the input area — the more realistic the sample, the more accurate the type inference
- Click "Generate" to produce Crystal struct definitions with property type annotations
- Copy the output into a .cr file in your Crystal project and add require "json" for serialization support
- Add JSON::Serializable include to each struct if you need automatic JSON parsing: include JSON::Serializable
- For database-backed models, change struct to class and include DB::Serializable instead
Why Use This Tool?
Tips & Best Practices
- Crystal structs are stack-allocated value types — use them for small, short-lived data. For larger objects or when you need inheritance, switch to class instead
- To make structs JSON-parseable, add include JSON::Serializable and use JSON.parse(json_string).as(YourStruct) for deserialization
- Crystal supports nilable types with the ? suffix: change property name : String to property name : String? for fields that may be nil at runtime
- Empty arrays default to Array(String) — if your API returns arrays of different types, manually adjust the generic parameter after generation
- Crystal compiles to native binary with zero runtime overhead — the generated structs have no reflection cost unlike Ruby's OpenStruct
Frequently Asked Questions
How does JSON map to Crystal types?
JSON strings map to String, integers map to Int32 (Crystal has explicit sizes: Int8, Int16, Int32, Int64), floats map to Float64, booleans map to Bool, null maps to Nil, arrays become Array(Type) with inferred element types, and nested objects become separate struct definitions with PascalCase names.
When should I avoid using this generator?
Skip this tool if you need Crystal union types (e.g. Int32 | String) — the generator cannot infer union types from a single JSON sample. Also avoid it if your data uses Int64 IDs that exceed Int32 range, or if you need JSON::Serializable mappings with custom key names via JSON::Field annotations.
What is a struct in Crystal and when should I use class instead?
A struct in Crystal is a stack-allocated value type — copying a struct copies its data. A class is heap-allocated and passed by reference. Use struct for small, immutable data objects (under ~32 bytes). Use class for larger objects, when you need inheritance, or when multiple variables should reference the same instance.
How do I make the generated structs JSON-parseable?
Add include JSON::Serializable to each struct definition. This mixin provides from_json and to_json methods. For nested structs, both the parent and child structs need the include. You can also add JSON::Field(key: "api_name") annotations when Crystal property names differ from JSON keys.
What is the property keyword in Crystal?
property declares both a getter and setter method for a struct or class field. Crystal also supports getter (read-only) and setter (write-only). Use property when you need to modify field values after creation, and getter when the data should be immutable.
Is my data sent to a server?
No. All type inference and code generation run entirely in your browser. Your JSON data never leaves your device — no network requests, no server-side processing, and no data retention.
Real-world Examples
Lucky framework API response model
Generate Crystal structs for an API response that returns user data with nested address information, ready for use in a Lucky web application.
{
"id": 1,
"name": "Alice",
"email": "alice@example.com",
"is_active": true,
"score": 98.5,
"tags": ["developer"],
"address": {
"street": "123 Main St",
"city": "Springfield"
}
}struct Address property street : String property city : String end struct User property id : Int32 property name : String property email : String property is_active : Bool property score : Float64 property tags : Array(String) property address : Address end
Configuration struct for a Crystal CLI tool
Create a Crystal struct for a CLI tool configuration file, with nullable fields for optional settings.
{
"host": "localhost",
"port": 3000,
"debug": false,
"logLevel": null
}struct Config property host : String property port : Int32 property debug : Bool property logLevel : Nil end