{"id":28758268,"url":"https://github.com/do-say-go/weirdjson","last_synced_at":"2025-06-17T04:06:18.722Z","repository":{"id":57285575,"uuid":"315946529","full_name":"DO-SAY-GO/WeirdJSON","owner":"DO-SAY-GO","description":"the JS/Node.JS library for encoding complex and unconventional data structures. Support for BigInts, TypedArrays, null, undefined, and Symbol. Multiple flavors available.","archived":false,"fork":false,"pushed_at":"2022-12-12T09:43:47.000Z","size":162,"stargazers_count":201,"open_issues_count":6,"forks_count":8,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-06-12T05:17:31.368Z","etag":null,"topics":["ascii","ascii85","base64","emoji","json","unicode","uuencode"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DO-SAY-GO.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"custom":"https://buy.stripe.com/bIY5lw7hL2Ur6LS3cM"}},"created_at":"2020-11-25T13:23:55.000Z","updated_at":"2025-02-07T08:47:44.000Z","dependencies_parsed_at":"2023-01-27T17:16:30.763Z","dependency_job_id":null,"html_url":"https://github.com/DO-SAY-GO/WeirdJSON","commit_stats":null,"previous_names":["c9fe/weird-json","do-say-go/weirdjson","dosyago/weirdjson"],"tags_count":22,"template":false,"template_full_name":null,"purl":"pkg:github/DO-SAY-GO/WeirdJSON","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DO-SAY-GO%2FWeirdJSON","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DO-SAY-GO%2FWeirdJSON/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DO-SAY-GO%2FWeirdJSON/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DO-SAY-GO%2FWeirdJSON/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DO-SAY-GO","download_url":"https://codeload.github.com/DO-SAY-GO/WeirdJSON/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DO-SAY-GO%2FWeirdJSON/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260288473,"owners_count":22986667,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["ascii","ascii85","base64","emoji","json","unicode","uuencode"],"created_at":"2025-06-17T04:06:17.935Z","updated_at":"2025-06-17T04:06:18.711Z","avatar_url":"https://github.com/DO-SAY-GO.png","language":"JavaScript","funding_links":["https://buy.stripe.com/bIY5lw7hL2Ur6LS3cM"],"categories":[],"sub_categories":[],"readme":"# :blue_heart: [weird json](https://github.com/c9fe/weird-json) [![npm](https://img.shields.io/npm/v/weird-json.svg?label=\u0026color=0080FF)](https://github.com/c9fe/weird-json/releases/latest) [![visitors+++](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2Fc9fe%2Fweird-json\u0026count_bg=%2379C83D\u0026title_bg=%23555555\u0026icon=\u0026icon_color=%23E7E7E7\u0026title=%28today%2Ftotal%29%20visitors%2B%2B%2B%20since%20Nov%2026%202020\u0026edge_flat=false)](https://hits.seeyoufarm.com) [![npm](https://img.shields.io/npm/dt/weird-json)](https://npmjs.com/package/weird-json)\n\nA menagerie of strange, encoded JSONs, for connoisseurs.\n\n# what?\n\n**TLDR** - JSON superset, supporting BigInts, TypedArrays, null, undefined, Symbol and more.\n\nWeirdJSON is a JavaScript / Node.JS library that allows you to serialize any JavaScript object to a \"JSON-like\" but extended, text representation. With weird-json, you can easily encode complex and unconventional data structures, including support for BigInts, TypedArrays, null, undefined, and Symbol. weird-json comes in a variety of flavors, including deepCopy, JSON36, JSON46, and JSON64, so you can choose the best option for your specific needs. Whether you're a JSON connoisseur or just looking to handle some weird data, weird-json has you covered!\n\n# features\n\nComes in a variety of flavors:\n\n- **deepCopy** - clones an object as deeply as possible. (Limitations: No support for functions because of closure inequality, no preservation of prototype chain for custom objects but all JavaScript builtin objects supported on the browser are handled (but not DOM/CSSOM API objects like Node, or XMLHttpRequest, CSSStyleSheetDeclaration), no cloning of unregistered Symbols (i.e, not created with Symbol.for), no support for WeakSet nor WeakMap. See [limitationisms](#limitationisms) for details.\n- JSON36 - JSON46 but coded down to (case-insensitive) A-Z0-9\n- JSON46 - Supports the full 17-plane Unicode 13, and codes it down to ASCII without Base64. HUZZAH!\n- JSON64 - JSON46 but encoded with irradix to a special base64\n\nSimple example:\n\n```js\n\u003e JSON36.stringify({a:[NaN, 1.23e72]})\n'dga002pabdeawacas1dk23edj72adfdh'\n\u003e JSON36.parse('dga002pabdeawacas1dk23edj72adfdh')\n{ a: [ NaN, 1.23e+72 ] }\n\u003e JSON36.stringify(489572349583759234857234958237459348734934958374n)\n'aoda0m5nl54p8yz1dcdby79z5ddxhjvv7qexya'\n\u003e JSON36.parse('aoda0m5nl54p8yz1dcdby79z5ddxhjvv7qexya')\n489572349583759234857234958237459348734934958374n\n```\n\n## usagistics\n\n```shell\n$ npm i --save weird-json\n$ node -r esm\nWelcome to Node.js v14.15.1.\nType \".help\" for more information.\n\u003e const {deepCopy} = require('weird-json');\n\u003e deepCopy(new Array(1,2,{c:3}))\n[ 1, 2, { c: 3 } ]\n\u003e import {deepCopy as deepCopy2} from 'weird-json';\n\u003e deepCopy(new Array(1,2,{c:3}))\n[ 1, 2, { lostWorld: 'JPark' } ]\n```\n\n## testimoanials\n\n----------\n\n\u003e Go where no Unicode JSON has gone before. Go where only ASCII can!\n\u003e\n\u003e \u0026mdash; J. (Son) F. Kennedy\n\n----------\n\n\u003e You stole our previous alphabet!\n\u003e\n\u003e \u0026mdash; NATO\n\n\n## get to know the current JSONs-in-residence\n\nThe merry little band of tricksters: *JSON46*, *JSON36*, *JSON37* and the ever-affable, *JSON38*\n\n### JSON46\n\nForged in the fires of Mordor, the hand-polished 46 runic sigils of our exclusive 46 line cover all your possible use cases. You can make a Chinese JSON, an emoji JSON, and then safely protect it and in the darkness bind it so only 36 alphanumerics plus 7 unique JSON structural symbols, plus 3 highly-coveted numeric specifiers (`e`, `+` and `-`) are present.  \n\nFeatures:\n\n- alphabet: a-z, 0-9, `:,\"[]{}.+-`\n- JSON superset, supports BigInt, TypedArrays, null, undefined and Symbol\n\nComplete ASCII. Complete URL safe. But not safe enough? Try *JSON36*. :tada:\n\n### JSON36\n\nLike JSON46, but encoded again into the 36ers: a-z, 0-9. Fully [NATO](https://www.nato.int/cps/fr/natohq/declassified_136216.htm) [compliant](https://archives.nato.int/phonetic-alphabet;isad).\n\n### JSON37\n\nLike JSON46, but compressed with LZW, then encoded into the 36ers: a-z, 0-9 plus `.` Also, NATO phonetic alphabet compliant.\n\n### JSON38\n\nLike JSON37, but separated into stanzas separted by `-` dash. Also, NATO phonetic alphabet OK.\n\n### JSON64\n\nLike JSON46, but instead of being coded down to ASCII we leave the unicode in, then encode it in a special Base64 powered by [irradix](https://github.com/c9fe/irradix) that uses bit packing.\n\n## examplings\n\nFrom the tests:\n```js\n  // simple example\n\n  const b = {\n    hi: \"💉💎 or 👦🏻👓⚡嗨，我唔係Gpt - 3寫嘅。 你叫咩名呀?\"\n  };\n  const bStr = JSON46.stringify(b);\n  const bStr2 = JSON36.stringify(b);\n  const bObj = JSON36.parse(bStr2);\n\n  /***\n\n  {\n    bStr: '{\"002w002x\":\"2qvd2qvi000w00330036000w2que2qrf2qtv07mp0gyw1edo0jdd0gt00fr6001z00340038000w0019000w001f0i5n0gzp09he000w0fog0gkr0gq10glp0gn4001r\"}',\n    bStr2: 'dga002w002xaba2qvdd2qvi000w00330036000w2que2qrf2qtv07mp0gyw1eddo0jdddd0gt00fr6001z00340038000w0019000w001f0i5n0gzp09he000w0fog0gkr0gq10glp0gn4001radh'\n  }\n\n  { bObj: { hi: '💉💎 or 👦🏻👓⚡嗨，我唔係Gpt - 3寫嘅。 你叫咩名呀?' } }\n\n  ***/\n\n  // more involved example\n\n  const a = {\n    name: 'Cris',\n    age: 36,\n    eo: {},\n    ea: [],\n    wo: {[NaN]:true},\n    mmm: undefined,\n    code: 3948573458972n,\n    hello: true,\n    xy: new Uint16Array(),\n    great: null,\n    hi: NaN,\n    xchakka: -Infinity,\n    bigExp: 2.95e77,\n    smallExp: 1.93e-81,\n    azza: new Uint8Array([9,10,11]),\n    happiness: [\n      { object: 999999n, z: NaN, p: Symbol.for(\"hello-kitty\") },\n      null,\n      \"CRIS\",\n      238947,\n      undefined,\n      NaN,\n      2234.1231,\n      34589358794234233498752345789345n,\n      { great: [true, false] },\n      [ \"ok\", Infinity ],\n      new Float64Array([1.123e+123, 9.06233419e-94])\n    ]\n  };\n  \n  const aStr = JSON46.stringify(a);\n  \n  /***\n  \n  '{\"0032002p0031002t\":\"001v0036002x0037\",\"002p002v002t\":\"r10\",\"003100310031\":\"u\",\"002r0033002s002t\":\"o1edy6os2k\",\"002w002t003000300033\":\"a\",\"002v0036002t002p0038\":\"v\",\"002w002x\":\"w\",\"003c002r002w002p002z002z002p\":\"z-\",\"002q002x002v001x003c0034\":\"s2.95e+77\",\"00370031002p00300030001x003c0034\":\"s1.93e-81\",\"002p003e003e002p\":\"x19.a.b\",\"002w002p00340034002x0032002t00370037\":[{\"0033002q002y002t002r0038\":\"olflr\",\"003e\":\"w\",\"0034\":\"y002w002t0030003000330019002z002x00380038003d\"},\"v\",\"001v002a0021002b\",\"r54df\",\"u\",\"w\",\"r1q2.4fjcq9k7\",\"o2l5hrv15xy2864k787t7l\",{\"002v0036002t002p0038\":[\"a\",\"b\"]},[\"0033002z\",\"z+\"],\"x81.123e+123f9.06233419e-94\"]}'\n  \n  ***/\n  \n  // or, in pretty printed form\n  \n  /***\n  \n  {\n    \"0032002p0031002t\": \"001v0036002x0037\",\n    \"002p002v002t\": \"r10\",\n    \"003100310031\": \"u\",\n    \"002r0033002s002t\": \"o1edy6os2k\",\n    \"002w002t003000300033\": \"a\",\n    \"002v0036002t002p0038\": \"v\",\n    \"002w002x\": \"w\",\n    \"003c002r002w002p002z002z002p\": \"z-\",\n    \"002q002x002v001x003c0034\": \"s2.95e+77\",\n    \"00370031002p00300030001x003c0034\": \"s1.93e-81\",\n    \"002p003e003e002p\": \"x19.a.b\",\n    \"002w002p00340034002x0032002t00370037\": [\n      {\n        \"0033002q002y002t002r0038\": \"olflr\",\n        \"003e\": \"w\",\n        \"0034\": \"y002w002t0030003000330019002z002x00380038003d\"\n      },\n      \"v\",\n      \"001v002a0021002b\",\n      \"r54df\",\n      \"u\",\n      \"w\",\n      \"r1q2.4fjcq9k7\",\n      \"o2l5hrv15xy2864k787t7l\",\n      {\n        \"002v0036002t002p0038\": [\n          \"a\",\n          \"b\"\n        ]\n      },\n      [\n        \"0033002z\",\n        \"z+\"\n      ],\n      \"x81.123e+123f9.06233419e-94\"\n    ]\n  }\n\n  ***/\n  \n  const aStr2 = JSON36.stringify(a);\n  \n  /***\n  \n  'dga0032002p0031002taba001v0036002x0037aca002p002v002tabar10aca003100310031abauaca002r0033002s002tabao1eddy6os2kaca002w002t003000300033abadaaca002v0036002t002p0038abavaca002w002xabawaca003dc002r002w002p002z002z002pabazdiaca002q002x002v001x003dc0034abas2dk95edj77aca00370031002p00300030001x003dc0034abas1dk93edi81aca002p003e003e002pabax19dkdadkdbaca002w002p00340034002x0032002t00370037abdedga0033002q002y002t002r0038abaolflraca003eabawaca0034abay002w002t0030003000330019002z002x00380038003ddadhcavaca001v002da0021002dbacar54ddfacauacawacar1q2dk4fjdcq9k7acao2l5hrv15xy2864k787t7lacdga002v0036002t002p0038abdeadaacadbadfdhcdea0033002zacazdjadfcax81dk123edj123f9dk06233419edi94adfdh'\n  \n  ***/\n  \n  const revivedA = JSON36.parse(aStr2);\n \n  console.log(util.inspect(revivedA, false, null, true)); \n  // tada\n  \n  {\n    name: 'Cris',\n    age: 36,\n    eo: {},\n    ea: [],\n    wo: {[NaN]:true},\n    mmm: undefined,\n    code: 3948573458972n,\n    hello: true,\n    xy: new Uint16Array(),\n    great: null,\n    hi: NaN,\n    xchakka: -Infinity,\n    bigExp: 2.95e77,\n    smallExp: 1.93e-81,\n    azza: new Uint8Array([9,10,11]),\n    happiness: [\n      { object: 999999n, z: NaN, p: Symbol.for(\"hello-kitty\") },\n      null,\n      \"CRIS\",\n      238947,\n      undefined,\n      NaN,\n      2234.1231,\n      34589358794234233498752345789345n,\n      { great: [true, false] },\n      [ \"ok\", Infinity ],\n      new Float64Array([1.123e+123, 9.06233419e-94])\n    ]\n  };\n  \n\n  // in node\n  require('assert').deepStrictEqual(a, aObj); // fine\n  require('assert').deepStrictEqual(b, bObj); // fine\n```\n\n## designagistics\n\n- can I have a JSON format that effortlessly supports Unicode everywhere without any problems?\n- can I have a text and coding format to make everything ASCII for transport that isn't affected by different apis for base64 in node JS and the browser?\n- can I have a JSON that supports Bigints and typed arrays as well as null undefined and symbols?\n- is there a encoding to ASCII text that I can easily access in JavaScript in the browser and in node without writing it myself nor importing a dependency?\n- what if I want to say JSON over the telephone or radio?\n\nAll these encoding designs are inspired by the availability of base 36 in Node and Browser, and also in people's brains.\n\n## get \n\nThem all:\n\n```console\n$ npm i --save weird-json\n```\n\n## usagisms\n\n```js\nimport {JSON36, JSON46, PrimeCode} from 'weird-json';\n```\n\n## technicalisters\n\nWe aim for equality based on [assert.deepStrictEqual](https://nodejs.org/api/assert.html#assert_assert_deepstrictequal_actual_expected_message), which has the following specifications:\n\n- Primitive values are compared using the SameValue Comparison, used by Object.is().\n- Type tags of objects should be the same.\n- [[Prototype]] of objects are compared using the Strict Equality Comparison.\n- Only enumerable \"own\" properties are considered.\n- Error names and messages are always compared, even if these are not enumerable properties.\n- Enumerable own Symbol properties are compared as well.\n- Object wrappers are compared both as objects and unwrapped values.\n- Object properties are compared unordered.\n- Map keys and Set items are compared unordered.\n- Recursion stops when both sides differ or both sides encounter a circular reference.\n- WeakMap and WeakSet comparison does not rely on their values. See below for further details.\n\n## roadiest mappings\n\n- [x] add support for BigInt\n- [x] add support for NaN, Infinity, null and undefined\n- [x] add typedarray support\n- [x] support floating point exponent notification\n- [x] add symbol support\n- [x] add support for Map and Set\n- [x] Add support for Date\n- [x] add deepCopy\n- [ ] implement json37, and json38\n- [ ] optimize speed\n- [ ] support Node.JS built-ins like Buffer, etc\n- [ ] revive prototype chain for instances of custom class or prototypal inheritance\n\n## preeori artus / anteeori artusismus\n\n- [yuwu9145/nest-object-deep-copy](https://github.com/yuwu9145/nest-object-deep-copy) doesn't support everything but supports cloning prototypes (:astonished:)\n\n## limitationisms\n\nNO support for:\n\n- WeakSet nor WeakMap, because values collected in these will have no other references on revivial, and so will not make sense to be in WeakMap nor WeakSet, and will not be guaranteed to be in there. Explore if you can use Map or Set instead.\n- unregistered Symbols. Because these will fail the equality test (DeepStrictEquality), by design of Symbol. Use registered Symbol's (Symbol.for) instead.\n- Functions. Because scope cannot be serialized in JavaScript at this time, and also because functions fail the equality test (DeepStrictEquality)\n\n## licensing\n\nDual Licensed under APache-2.0 and the Artistic License. You can choose. \n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdo-say-go%2Fweirdjson","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdo-say-go%2Fweirdjson","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdo-say-go%2Fweirdjson/lists"}