SuperJSON for Elixir

Hex.pmDocumentationLicense: MIT

A high-fidelity SuperJSON decoder and encoder for Elixir. This is a complete Elixir port of the original TypeScript SuperJSON library.

Seamlessly serialize and rehydrate JavaScript/TypeScript complex types (Dates, MapSets, Maps, BigInts, Regexps, URLs, Errors, and referential equalities) into native Elixir data structures.

Perfect for communicating with JS/TS frameworks that use SuperJSON for payload serialization, such as Trigger.dev, tRPC, Remix, Blitz.js, or Next.js.

Installation

Add superjson to your list of dependencies in mix.exs:

def deps do
[
{:superjson, "~> 0.1.0"}
]
end

Features

Usage

Decoding (JS -> Elixir)

Usually, you will receive a raw SuperJSON string from an API or webhook. You can decode it directly into native Elixir structs: (See test/super_json/readme_test.exs:L6-L29 for the validation of this example)

json_string = """
{
"json": {
"createdAt": "2023-10-10T15:20:00Z",
"amount": "9007199254740991",
"pattern": "/abc/i"
},
"meta": {
"values": {
"createdAt": ["Date"],
"amount": ["bigint"],
"pattern": ["regexp"]
}
}
}
"""
{:ok, result} = SuperJSON.decode(json_string)
# Or raise on error:
# result = SuperJSON.decode!(json_string)
# result["createdAt"] => ~U[2023-10-10 15:20:00Z]
# result["amount"] => 9007199254740991
# result["pattern"] => ~r/abc/i

If your HTTP client (like Req or HTTPoison) automatically parses JSON responses into Elixir maps using Jason, you can simply pass that pre-parsed map directly to SuperJSON:

# Assume `response.body` was already parsed by your HTTP client:
# response.body = %{"json" => ..., "meta" => ...}
{:ok, result} = SuperJSON.decode(response.body)

Encoding (Elixir -> JS)

Pass native Elixir structs, MapSets, and atoms, and get a SuperJSON payload ready to be sent to a JavaScript client. (See test/super_json/readme_test.exs:L31-L55 for the validation of this example)

my_data = %{
"date" => ~U[2026-01-01 12:00:00Z],
"set" => MapSet.new([1, 2, :nan]),
"url" => URI.parse("https://www.example.com")
}
encoded = SuperJSON.encode(my_data)
# %{
# "json" => %{
# "date" => "2026-01-01T12:00:00Z",
# "set" => [1, 2, "NaN"],
# "url" => "https://www.example.com"
# },
# "meta" => %{
# "values" => %{
# "date" => ["Date"],
# "set" => ["set", %{"2" => ["number"]}],
# "url" => ["URL"]
# }
# }
# }
# You can also use `SuperJSON.encode!/1` to return a raw JSON string directly:
# json_string = SuperJSON.encode!(my_data)

License

This package is licensed under the MIT License.