JSON to Elixir Struct Generator

Generate Elixir defmodule with defstruct and @type t specifications from JSON data.

What is JSON to Elixir Struct Generator?

Elixir structs are named maps with a fixed set of keys and default values, defined inside defmodule blocks with defstruct. They provide compile-time guarantees about which keys exist and are the idiomatic way to model domain data in Elixir and Phoenix applications. This generator transforms your JSON data into complete Elixir module definitions, each containing a defstruct with default values and an @type t specification for dialyzer type checking. It infers Elixir-native types from JSON values — strings become String.t(), integers become integer(), floats become float(), booleans become boolean() — and recursively handles nested objects as separate module definitions with proper children-first compilation ordering.

How to Use

  1. Set the module prefix in the options bar to match your OTP application namespace (e.g. MyApp.Accounts.)
  2. Paste your JSON object into the input area — the tool requires a JSON object, not an array or primitive
  3. Click "Generate" to produce defmodule definitions with defstruct and @type t specifications
  4. Review the generated code: nested objects appear as separate modules before the root module
  5. Copy the output into your Elixir project under the lib/ directory matching your module hierarchy
  6. Run dialyzer to verify type specifications match your actual data patterns

Why Use This Tool?

Generates production-ready Elixir modules with both defstruct defaults and @type t specs for dialyzer compliance
Automatic type inference maps JSON strings to String.t(), integers to integer(), floats to float(), and booleans to boolean()
Nested JSON objects become separate defmodule definitions, keeping your codebase modular and composable
Atom keys follow Elixir conventions — the generated struct fields use the same key names as your JSON
Children-first module ordering ensures referenced modules compile before the modules that depend on them
Default values are set to nil for all fields, letting you override specific defaults in your application code

Tips & Best Practices

  • Provide realistic sample data because type inference is driven by actual JSON values — a float like 3.0 produces float(), not integer()
  • Set the module prefix to match your OTP app structure so generated modules fit naturally into your supervision tree and aliases
  • Nested objects become separate modules named with the prefix plus PascalCase field name (e.g. MyApp.RootAddress for an "address" field)
  • Null values are typed as nil | term() for flexibility — consider narrowing to a specific type in production code
  • After pasting into your project, add @enforce_keys if certain fields must always be provided when creating the struct

Frequently Asked Questions

How are JSON types mapped to Elixir types?

JSON strings become String.t(), integers become integer(), floats become float(), booleans become boolean(), null becomes nil | term(), empty arrays become list(), and non-empty arrays become [ElementType] where the element type is inferred from the first item. Nested objects generate separate modules with their own .t() type reference.

What is defstruct and how does it differ from a regular map?

defstruct defines a struct — a tagged map with a fixed set of keys and default values. Unlike regular maps, structs provide compile-time guarantees about key existence, support pattern matching on the struct name, and are the standard way to define domain models in Elixir. They also enable protocols and derive implementations for Jason.Encoder, Inspect, and other behaviors.

When should I NOT use generated Elixir structs?

Avoid using generated structs when your JSON data has highly dynamic or unpredictable keys, since structs require a fixed set of fields. For API responses with varying shapes, consider using plain maps with Access or pattern matching instead. Also, if you need embedded schemas with changeset validation in Phoenix, use Ecto.Schema rather than plain structs.

How are nested objects handled?

Each nested JSON object becomes its own defmodule with a separate defstruct and @type t definition. Modules are ordered children-first so that referenced modules compile before the modules that use them. The parent struct references the child module by its full name (prefix + PascalCase field name) with the .t() type specification.

What is the module prefix for?

The module prefix sets the namespace for all generated modules. For example, with prefix "MyApp.Accounts.", a "User" struct becomes "MyApp.Accounts.User". This follows the Elixir convention of organizing modules under an OTP application namespace, making it easy to alias and import in your application code.

Is my JSON data sent to a server?

No. All code generation happens entirely in your browser. Your JSON data never leaves your device, so you can safely convert sensitive API responses or database records.

Real-world Examples

Phoenix API Response Modeling

Convert a JSON API response into Elixir structs for type-safe pattern matching in your Phoenix controller or LiveView.

Input
{"id": 1, "name": "Alice", "email": "[email protected]", "is_active": true, "address": {"street": "123 Main St", "city": "Springfield"}}
Output
defmodule MyApp.Address do
  @type t :: %__MODULE__{
    street: String.t(),
    city: String.t()
  }

  defstruct [street: nil, city: nil]
end

defmodule MyApp.Root do
  @type t :: %__MODULE__{
    id: integer(),
    name: String.t(),
    email: String.t(),
    is_active: boolean(),
    address: MyApp.Address.t()
  }

  defstruct [id: nil, name: nil, email: nil, is_active: nil, address: nil]
end

Ecto-Compatible Schema Scaffolding

Generate struct definitions as a starting point for Ecto schemas — then add field types, changesets, and validations.

Input
{"title": "My Post", "views": 150, "published": false, "tags": ["elixir", "phoenix"]}
Output
defmodule MyApp.Root do
  @type t :: %__MODULE__{
    title: String.t(),
    views: integer(),
    published: boolean(),
    tags: [String.t()]
  }

  defstruct [title: nil, views: nil, published: nil, tags: nil]
end

Related Tools