{"id":9243565,"url":"https://github.com/rowtype-yoga/purescript-yoga-json","last_synced_at":"2026-01-18T17:33:55.879Z","repository":{"id":37792473,"uuid":"490606975","full_name":"rowtype-yoga/purescript-yoga-json","owner":"rowtype-yoga","description":null,"archived":false,"fork":false,"pushed_at":"2025-03-01T11:54:47.000Z","size":163,"stargazers_count":17,"open_issues_count":5,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-10-10T21:34:16.347Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://pursuit.purescript.org/packages/purescript-yoga-json","language":"PureScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rowtype-yoga.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-05-10T08:24:44.000Z","updated_at":"2025-09-18T21:19:50.000Z","dependencies_parsed_at":"2024-09-14T07:33:47.560Z","dependency_job_id":null,"html_url":"https://github.com/rowtype-yoga/purescript-yoga-json","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/rowtype-yoga/purescript-yoga-json","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rowtype-yoga%2Fpurescript-yoga-json","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rowtype-yoga%2Fpurescript-yoga-json/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rowtype-yoga%2Fpurescript-yoga-json/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rowtype-yoga%2Fpurescript-yoga-json/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rowtype-yoga","download_url":"https://codeload.github.com/rowtype-yoga/purescript-yoga-json/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rowtype-yoga%2Fpurescript-yoga-json/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28544925,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T14:59:57.589Z","status":"ssl_error","status_checked_at":"2026-01-18T14:59:46.540Z","response_time":98,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-05-08T00:10:04.605Z","updated_at":"2026-01-18T17:33:55.863Z","avatar_url":"https://github.com/rowtype-yoga.png","language":"PureScript","funding_links":[],"categories":["Json"],"sub_categories":["Http routing"],"readme":"# purescript-yoga-json\n\n`yoga-json` is a light-weight and simple json library for purescript. \n\n**Note**: This library was initially forked from the amazing [simple-json](https://github.com/justinwoo/purescript-simple-json) ([MIT Licence](./LICENSE/simple-json.LICENSE)).\nReplace your imports from `Simple.JSON` to `Yoga.JSON` to migrate.\n## Table of Contents\n* [features](#features)\n* [installation](#installation)\n* [usage](#usage)\n\n## Features\n\n* 😌 simple and easy to use json codecs\n* 🪶 light-weight\n* 🤖 built-in support for many common types (`Sum` types, Tuples, BigInts, Maps, JSDate, DateTime, Eithers, NonEmptyStrings )\n* 🖍 human-friendly error reporting \n\n## Installation\n\n```\nspago install yoga-json\n```\n\n## Usage\n\n`purescript-yoga-json` basically provides two functions `writeJSON` and `readJSON`.\n\nUse `writeJSON` to serialise a type to a JSON string:\n\n```purescript\nimport Yoga.JSON as JSON\n\nserialised :: String\nserialised =\n  JSON.writeJSON { first_name: \"Lola\", last_name: \"Flores\" }\n  -- {\"last_name\":\"Flores\",\"first_name\":\"Lola\"}\n```\n\nUse `readJSON` to deserialise a JSON string:\n```purescript\nimport Yoga.JSON as JSON\n\ndeserialised :: Either MultipleErrors { first_name :: String, last_name :: String } \ndeserialised = JSON.readJSON \"\"\"{ \"first_name\": \"Lola\", \"last_name\": \"Flores\" }\"\"\"\n-- Right { first_name: \"Lola\", last_name: \"Flores\" }\n```\n\nAs the parsing can fail, `readJSON` returns an `Either`, potentially containing a `Left` data constructor with `MultipleErrors`. If you don't care about the specific errors, you can use `readJSON_`, which returns a `Maybe`:\n\n```purescript\ndeserialised :: Maybe { first_name :: String, last_name :: String } \ndeserialised = JSON.readJSON_ \"\"\"{ \"first_name\": \"Lola\", \"last_name\": \"Flores\" }\"\"\"\n-- Just { first_name: \"Lola\", last_name: \"Flores\" }\n```\n\n\n## Sum types\n\n`purescript-yoga-json` provides utility functions to easily generate serialisers and deserialisers for your sum types.\n\nLet's start with a simple example of a sum type where our data constructors do not contain any further values:\n\n```\nimport Data.Either (Either)\nimport Data.Generic.Rep (class Generic)\nimport Yoga.JSON as JSON\nimport Yoga.JSON.Generics (genericReadForeignEnum, genericWriteForeignEnum)\nimport Yoga.JSON.Generics.EnumSumRep as Enum\n\ndata MyEnum = Enum1 | Enum2 | Enum3\n```\n\nNow, we need to derive a `Generic` instance for it:\n\n```\nderive instance Generic MyEnum _\n-- and optionally a Show instance\ninstance Show MyEnum where\n  show = genericShow\n```\n\nNext, we define a `WriteForeign` instance and implement the `writeImpl` function using `genericWriteForeignEnum Enum.defaultOptions`. \n\n```purescript\ninstance WriteForeign MyEnum\n  where\n  writeImpl = genericWriteForeignEnum Enum.defaultOptions\n```\n\nSimilarly, we implement the `ReadForeign` instance using `genericReadForeignEnum Enum.defaultOptions`\n```purescript\ninstance ReadForeign MyEnum\n  where\n  readImpl = genericReadForeignEnum Enum.defaultOptions\n```\n\nThat's all, we can now serialise our data type:\n```purescript\nserialised = writeJSON { \"myEnum\": Enum3 }\n-- {\"myEnum\":\"Enum3\"}\n```\nand deserialise it:\n```purescript\ndeserialised :: E { \"myEnum\" :: MyEnum }\ndeserialised = readJSON serialised\n-- Right { myEnum: Enum3 }\n```\n\n### Writing custom codecs\n\nIn order to write your own, custom codecs you will need to provide instances for `WriteForeign` and `ReadForeign`. \n\nLet's see an example. We define a simple data type `TrafficLight` that has three data constructors `Red`, `Yellow` and `Green`:\n```purescript\ndata TrafficLight = Red | Yellow | Green\n```\nWe would like to serialise these constructors as lower case strings `\"red\"`, `\"yellow\"` and `\"green\"`.\n\nFirst we need to provide an implementation for the `WriteForeign` type class, that tells `yoga-json` how to serialise the type. We pattern match on the three different data constructors and write them as the three `String`s red, yellow and green, using the same `writeImpl` function:\n```purescript\ninstance WriteForeign TrafficLight where\n  writeImpl Red = writeImpl \"red\"\n  writeImpl Yellow = writeImpl \"yellow\"\n  writeImpl Green = writeImpl \"green\"\n```\nThis works, because `yoga-json` already knows how to serialise a `String`. \n\nSimilarly, we need to provide an implementation for the `ReadForeign` type class, that tells `yoga-json` how to deserialise the type. We start by deserialising into a primitive type, typically a String or an Object, and then convert it to our desired Purescript type.\n\nSince we don't know the input `String`, it might contain invalid data and therefore deserialisation might fail. `yoga-json` uses the `ExceptT` monad to reflect this. We can return valid values using `pure` and `fail` on invalid values:\n\n```purescript\ninstance ReadForeign TrafficLight where\n  readImpl json = do\n    -- deserialise into a string\n    str :: String \u003c- readImpl json  \n    -- now we pattern match on our valid types\n    case str of\n      \"red\" -\u003e pure Red\n      \"yellow\" -\u003e pure Yellow\n      \"green\" -\u003e pure Green\n      -- and fail if we get an invalid type\n      other -\u003e fail $ ForeignError $ \"Failed to parse \" \u003c\u003e other \u003c\u003e \" as TrafficLight\"\n```\n\nNow we can serialise our data type:\n```purescript\nserialised = writeJSON { \"trafficLight\": Red }\n-- {\"trafficLight\":\"red\"}\n```\n\nand deserialise it:\n```purescript\ndeserialised :: E { \"trafficLight\" :: TrafficLight }\ndeserialised = readJSON \"\"\"{ \"trafficLight\": \"green\" }\"\"\"\n-- Right { trafficLight: Green }\n\ndeserialisedUnknown :: E { \"trafficLight\" :: TrafficLight }\ndeserialisedUnknown = readJSON \"\"\"{ \"trafficLight\": \"purple\" }\"\"\"\n-- Left (NonEmptyList (NonEmpty (ErrorAtProperty \"trafficLight\" (ForeignError \"Failed to parse purple as TrafficLight\")) Nil))\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frowtype-yoga%2Fpurescript-yoga-json","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frowtype-yoga%2Fpurescript-yoga-json","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frowtype-yoga%2Fpurescript-yoga-json/lists"}