Skip to content

wireform-ion

wireform-ion implements Amazon Ion, a superset of JSON designed for high-volume structured data in AWS services such as QLDB and Ion-based data lakes. Ion supports symbols, timestamps, decimals, and a rich type system in both text and binary forms. Use this package when you exchange Ion payloads with AWS tooling or need schema-checked Ion documents in Haskell.

  • Template Haskell deriving via deriveIon from Ion.Derive, with wireform-derive annotations; Generic defaults (empty instances) work for simple uncustomized records
  • Ion Schema Language (ISL) parser for declarative schema definitions
  • Schema-driven codegen that emits Haskell types and codec stubs from ISL
  • QuasiQuoter for embedding Ion text literals at compile time
  • Dynamic values via the untyped Value ADT for exploratory processing

Derive Ion codecs for a record and round-trip through binary Ion:

{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE TemplateHaskell #-}
module Metrics where
import Ion.Class (ToIon, FromIon, encodeIon, decodeIon)
import Ion.Derive (deriveIon)
import GHC.Generics (Generic)
import Data.Text (Text)
data Metric = Metric
{ metricName :: !Text
, metricValue :: !Double
}
deriving stock (Show, Eq, Generic)
$(deriveIon ''Metric)
publish :: Metric -> ByteString
publish m = encodeIon m
consume :: ByteString -> Either String Metric
consume bs = decodeIon bs

For simple records with no custom wire naming, Generic defaults also work: declare empty instance ToIon Metric and instance FromIon Metric after deriving stock (Show, Eq, Generic). Field names go to the wire verbatim and annotations are not supported.

For schema-first workflows, define types in ISL and splice them at compile time with the QuasiQuoter:

{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
module MetricsSchema where
import Ion.QQ (isl)
[isl|
type::{ name: Metric, fields: { name: string, value: float } }
|]

This parses the ISL definition and generates a Haskell record with ToIon and FromIon instances that match the schema field names and types.

wireform-ion encode + decode (Person record) wireform-ion encode + decode (Person record) lower is better · ns · ghc-9.8.4 on darwin-aarch64, criterion 1.6.5 0 12500 25000 37500 50000 330 403 38449 41835 single Person [Person] x 100 encode decode wireform-ion encode + decode (Person record) lower is better · ns · ghc-9.8.4 on darwin-aarch64, criterion 1.6.5 0 12500 25000 37500 50000 330 403 38449 41835 single Person [Person] x 100 encode decode
Operationencodedecoderatio
single Person330 ns403 ns1.22x
[Person] x 10038449 ns41835 ns1.09x

Last run 2026-06-27 11:35:54 UTC. ghc-9.8.4 on darwin-aarch64, criterion 1.6.5.

Sub-microsecond single-record performance. Batch operations scale linearly.

The chart and table above are regenerated by wireform-stats from wireform-ion/bench-results/summary/ion-encode-decode.json — the same source the README chart is built from.

ModulePurpose
Ion.ClassToIon / FromIon, encodeIon, decodeIon
Ion.Encode / Ion.DecodeLow-level binary Ion encode and decode
Ion.ValueDynamic untyped Value ADT
Ion.SchemaLangIon Schema Language parser
Ion.ISLSchema / Ion.ISLCodeGenISL AST and Haskell code generator
Ion.QQQuasiQuoter for Ion text literals
Ion.DeriveTemplate Haskell deriver with wireform-derive annotations