# `JSON`
[🔗](https://github.com/elixir-lang/elixir/blob/v1.20.1/lib/elixir/lib/json.ex#L280)

JSON encoding and decoding.

Both encoder and decoder fully conform to [RFC 8259](https://tools.ietf.org/html/rfc8259) and
[ECMA 404](https://ecma-international.org/publications-and-standards/standards/ecma-404/)
standards.

## Encoding

Elixir primitive types are encoded to JSON as follows:

| **Elixir**                 | **JSON** |
|----------------------------|----------|
| `integer() \| float()`     | Number   |
| `true \| false `           | Boolean  |
| `nil`                      | Null     |
| `binary()`                 | String   |
| `atom()`                   | String   |
| `list()`                   | Array    |
| `%{String.Chars.t() => _}` | Object   |

You may also implement the `JSON.Encoder` protocol for custom data structures.
Some built-in data-structures already derive the `JSON.Encoder` protocol:

| **Elixir**             | **JSON**        |
|------------------------|-----------------|
| `Date.t()`             | ISO 8601 string |
| `Time.t()`             | ISO 8601 string |
| `DateTime.t()`         | ISO 8601 string |
| `NaiveDateTime.t()`    | ISO 8601 string |
| `Duration.t()`         | ISO 8601 string |

## Decoding

Elixir types are decoded from JSON as follows:

| **JSON** | **Elixir**             |
|----------|------------------------|
| Number   | `integer() \| float()` |
| Boolean  | `true \| false`        |
| Null     | `nil`                  |
| String   | `binary()`             |
| Object   | `%{binary() => _}`     |

# `decode_error_reason`
*since 1.18.0* 

```elixir
@type decode_error_reason() ::
  {:unexpected_end, non_neg_integer()}
  | {:invalid_byte, non_neg_integer(), byte()}
  | {:unexpected_sequence, non_neg_integer(), binary()}
```

# `decoders`
*since 1.18.0* 

```elixir
@type decoders() :: [
  array_start: (term() -&gt; term()),
  array_push: (term(), term() -&gt; term()),
  array_finish: (term(), term() -&gt; {term(), term()}),
  object_start: (term() -&gt; term()),
  object_push: (term(), term(), term() -&gt; term()),
  object_finish: (term(), term() -&gt; {term(), term()}),
  float: (String.t() -&gt; term()),
  integer: (String.t() -&gt; term()),
  string: (String.t() -&gt; term()),
  null: term()
]
```

Decoders for customizing JSON decoding behavior.

# `encoder`
*since 1.18.0* 

```elixir
@type encoder() :: (term(), encoder() -&gt; iodata())
```

# `decode`
*since 1.18.0* 

```elixir
@spec decode(binary()) :: {:ok, term()} | {:error, decode_error_reason()}
```

Decodes the given JSON.

Returns `{:ok, decoded}` or `{:error, reason}`.

## Examples

    iex> JSON.decode("[null,123,\"string\",{\"key\":\"value\"}]")
    {:ok, [nil, 123, "string", %{"key" => "value"}]}

## Error reasons

The error tuple will have one of the following reasons.

  * `{:unexpected_end, offset}` if `binary` contains incomplete JSON value
  * `{:invalid_byte, offset, byte}` if `binary` contains unexpected byte or invalid UTF-8 byte
  * `{:unexpected_sequence, offset, bytes}` if `binary` contains invalid UTF-8 escape

# `decode`
*since 1.18.0* 

```elixir
@spec decode(binary(), term(), decoders()) ::
  {term(), term(), binary()} | {:error, decode_error_reason()}
```

Decodes the given JSON with the given decoders.

Returns `{decoded, acc, rest}` or `{:error, reason}`.
See `decode/1` for the error reasons.

## Decoders

All decoders are optional. If not provided, they will fall back to
implementations used by the `decode/1` function:

  * for `array_start`: `fn _ -> [] end`
  * for `array_push`: `fn elem, acc -> [elem | acc] end`
  * for `array_finish`: `fn acc, old_acc -> {Enum.reverse(acc), old_acc} end`
  * for `object_start`: `fn _ -> [] end`
  * for `object_push`: `fn key, value, acc -> [{key, value} | acc] end`
  * for `object_finish`: `fn acc, old_acc -> {Map.new(acc), old_acc} end`
  * for `float`: `&String.to_float/1`
  * for `integer`: `&String.to_integer/1`
  * for `string`: `&Function.identity/1`
  * for `null`: the atom `nil`

For streaming decoding, see Erlang's [`:json`](`:json`) module.

# `decode!`
*since 1.18.0* 

```elixir
@spec decode!(binary()) :: term()
```

Decodes the given JSON but raises an exception in case of errors.

Returns the decoded content. See `decode/1` for possible errors.

## Examples

    iex> JSON.decode!("[null,123,\"string\",{\"key\":\"value\"}]")
    [nil, 123, "string", %{"key" => "value"}]

# `encode!`
*since 1.18.0* 

```elixir
@spec encode!(term(), encoder()) :: binary()
```

Encodes the given term to JSON as a binary.

The second argument is a function that is recursively
invoked to encode a term.

> #### IO and performance {: .tip}
>
> If you need to encode data to be sent over the network
> or written to the filesystem, consider using the more
> efficient `encode_to_iodata!/2`.

## Examples

    iex> JSON.encode!([123, "string", %{key: "value"}])
    "[123,\"string\",{\"key\":\"value\"}]"

# `encode_to_iodata!`
*since 1.18.0* 

```elixir
@spec encode_to_iodata!(term(), encoder()) :: iodata()
```

Encodes the given term to JSON as an iodata.

This is the most efficient format if the JSON is going to be
used for IO purposes.

The second argument is a function that is recursively
invoked to encode a term.

## Examples

    iex> data = JSON.encode_to_iodata!([123, "string", %{key: "value"}])
    iex> IO.iodata_to_binary(data)
    "[123,\"string\",{\"key\":\"value\"}]"

# `protocol_encode`
*since 1.18.0* 

```elixir
@spec protocol_encode(term(), encoder()) :: iodata()
```

This is the default encode implementation passed to `encode!/1`.

This function is most typically passed as second argument to
`encode!/2` and `encode_to_iodata!/2`. The default implementation
is an optimized dispatch to the `JSON.Encoder` protocol.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
