JSON to Crystal Struct Generator

Generate Crystal struct definitions with property type annotations from JSON data.

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

  1. Paste a representative JSON response from your API into the input area — the more realistic the sample, the more accurate the type inference
  2. Click "Generate" to produce Crystal struct definitions with property type annotations
  3. Copy the output into a .cr file in your Crystal project and add require "json" for serialization support
  4. Add JSON::Serializable include to each struct if you need automatic JSON parsing: include JSON::Serializable
  5. For database-backed models, change struct to class and include DB::Serializable instead

Why Use This Tool?

Infers Crystal-specific types like Int32 and Float64 rather than generic number types, matching Crystal's explicit integer sizing conventions
Struct definitions use property declarations that provide both getter and setter methods, following Crystal's idiomatic struct pattern
Nested objects become separate struct definitions ordered children-first, ensuring the Crystal compiler resolves type references correctly
Arrays use the explicit Array(Type) syntax which is clearer in struct definitions than the shorthand Type[] syntax
Null values are typed as Nil, enabling Crystal's nilable type unions (e.g. String?) when you add the ? suffix manually

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.

Input
{
  "id": 1,
  "name": "Alice",
  "email": "alice@example.com",
  "is_active": true,
  "score": 98.5,
  "tags": ["developer"],
  "address": {
    "street": "123 Main St",
    "city": "Springfield"
  }
}
Output
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.

Input
{
  "host": "localhost",
  "port": 3000,
  "debug": false,
  "logLevel": null
}
Output
struct Config
  property host : String
  property port : Int32
  property debug : Bool
  property logLevel : Nil
end

Related Tools