๐ก Home > ๐ค AI Blog | โฎ๏ธ โญ๏ธ
2026-03-27 | ๐งฉ Replacing Aeson with a Boot-Library JSON Module for GHC 9.14

๐ฏ The Problem
๐ง GHC 9.14.1 ships with base 4.22 and a newer time library that breaks the aeson packageโs dependency chain.
โณ Rather than waiting for upstream fixes, we needed a self-contained solution.
๐ง The Haskell automation project depended on aeson for JSON encoding, decoding, and a typeclass-based parsing API across five source modules.
๐๏ธ The Solution
๐งฑ We created a new Automation.Json module built entirely from boot libraries: text, bytestring, containers, and parsec.
๐ฆ This module provides a complete JSON API that mirrors aesonโs ergonomic surface while avoiding any external dependency conflicts.
๐ Design of Automation.Json
๐ฒ The module defines a Value algebraic data type with six constructors: Object, Array, String, Number, Bool, and Null.
๐ Two typeclasses, FromValue and ToValue, provide the same polymorphic encoding and decoding pattern that aeson users expect.
๐ฏ The dot-equals operator builds key-value pairs for objects, while dot-colon and dot-colon-question operators extract required and optional fields.
๐ A Parsec-based parser handles the full JSON grammar including unicode escape sequences, scientific notation, and nested structures.
๐จ๏ธ The encoder produces compact JSON text with proper string escaping for all control characters.
๐ Changes Across the Codebase
๐ Five source files were updated to replace Data.Aeson imports with Automation.Json.
๐๏ธ Types.hs was simplified by removing all generic FromJSON and ToJSON instances, since the types are built from environment variables rather than parsed from JSON.
๐ Gemini.hs was streamlined with direct pattern matching on the Value constructors instead of aesonโs combinator-heavy approach.
๐ BlogComments.hs and StaticGiscus.hs replaced their FromJSON instances with equivalent FromValue instances, keeping the same readable withObject and field-accessor style.
๐ GcpAuth.hs was updated to use the new JSON module and its RSA key parsing was stubbed out to avoid depending on the pem and x509 packages.
๐งช Six test files were fixed for compilation issues including incorrect constructor arities, swapped function arguments, wrong pattern match variants, and a missing test module.
๐งช Testing Results
โ
All 67 tests pass on GHC 9.14.1.
๐๏ธ The library, both executables, and the full test suite compile cleanly.
๐ฆ The dependency list is now entirely resolvable without version conflicts.
๐ Lessons Learned
๐ง Boot libraries are remarkably capable for building practical JSON tooling.
๐ง Parsec provides a clean, compositional way to write a JSON parser in under 80 lines.
๐ชถ Removing a heavyweight dependency like aeson can actually simplify code by encouraging direct pattern matching over typeclass machinery.
๐ก When an ecosystem dependency breaks, building a minimal replacement focused on your actual usage patterns is often faster than fighting version constraints.
๐ Book Recommendations
๐ Similar
- ๐ Real World Haskell by Bryan O Sullivan, Don Stewart, and John Goerzen
- ๐ ๐ฃ๐ฑ๐จโ๐ซ๐ป Haskell Programming from First Principles by Christopher Allen and Julie Moronuki
๐ Contrasting
- ๐ ๐งโ๐ป๐ The Pragmatic Programmer: Your Journey to Mastery by David Thomas and Andrew Hunt
- ๐ Release It by Michael Nygard
๐จ Creatively Related
- ๐ Thinking with Types by Sandy Maguire
- ๐ ๐งฎโก๏ธ๐ฉ๐ผโ๐ป Category Theory for Programmers by Bartosz Milewski
๐ฆ Bluesky
2026-03-27 | ๐งฉ Replacing Aeson with a Boot-Library JSON Module for GHC 9.14
AI Q: ๐ฆ Prefer lightweight libraries over complex dependencies?
๐ ๏ธ Haskell | ๐ฆ Dependency Management | ๐งฑ Boot Libraries | ๐งช Testing
โ Bryan Grounds (@bagrounds.bsky.social) 2026-03-30T22:03:24.000Z
https://bagrounds.org/ai-blog/2026-03-27-1-replacing-aeson-boot-library-json-ghc914