{"id":13724929,"url":"https://github.com/lucagez/slow-json-stringify","last_synced_at":"2025-04-12T23:39:27.652Z","repository":{"id":41293860,"uuid":"184280284","full_name":"lucagez/slow-json-stringify","owner":"lucagez","description":"The slowest stringifier in the known universe. Just kidding, it's the fastest (:","archived":false,"fork":false,"pushed_at":"2023-01-03T20:43:59.000Z","size":565,"stargazers_count":478,"open_issues_count":20,"forks_count":18,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-12T23:39:18.883Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://github.com/lucagez/slow-json-stringify","language":"JavaScript","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/lucagez.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}},"created_at":"2019-04-30T14:45:22.000Z","updated_at":"2025-03-27T16:07:22.000Z","dependencies_parsed_at":"2023-02-01T10:01:34.298Z","dependency_job_id":null,"html_url":"https://github.com/lucagez/slow-json-stringify","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucagez%2Fslow-json-stringify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucagez%2Fslow-json-stringify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucagez%2Fslow-json-stringify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucagez%2Fslow-json-stringify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lucagez","download_url":"https://codeload.github.com/lucagez/slow-json-stringify/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248647255,"owners_count":21139081,"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":[],"created_at":"2024-08-03T01:02:07.152Z","updated_at":"2025-04-12T23:39:27.621Z","avatar_url":"https://github.com/lucagez.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"sjs.svg\" height=\"200px\" alt=\"slow-json-stringify logo\" /\u003e\n  \u003cbr\u003e\n  \u003ca href=\"https://travis-ci.org/lucagez/slow-json-stringify\"\u003e\u003cimg src=\"https://travis-ci.com/lucagez/slow-json-stringify.svg?branch=master\" alt=\"travis\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.npmjs.org/package/slow-json-stringify\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/slow-json-stringify.svg?style=flat\" alt=\"npm\"\u003e\u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/badge/license-MIT-f1c40f.svg\" alt=\"MIT\"\u003e\n  \u003ca href=\"https://unpkg.com/slow-json-stringify\"\u003e\u003cimg src=\"https://img.badgesize.io/https://unpkg.com/slow-json-stringify/dist/sjs.js?compression=gzip\" alt=\"gzip size\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n# SJS\n\nThe slowest stringifier in the known universe. Just kidding, it's the fastest (:\n\n## TOC\n\n  - [TL;DR](#tldr)\n  - [Installation](#installation)\n  - [How it works](#how-it-works)\n  - [Caveats](#caveats)\n  - [Benchmarks](#benchmarks)\n      - [Running the benchmarks](#running-the-benchmarks)\n      - [Test machine](#test-machine)\n      - [Some numbers](#some-numbers)\n  - [Usage](#usage)\n      - [Supported types](#supported-types)\n      - [Defining a schema](#defining-a-schema)\n      - [Defining schema with simple array](#defining-schema-with-simple-array)\n      - [Defining schema with complex array](#defining-schema-with-complex-array)\n      - [Defining schema with nested objects](#defining-schema-with-nested-objects)\n  - [Serializers](#serializers)\n  - [API](#api)\n      - [sjs](#sjs)\n      - [escape](#escape)\n  - [License](#license)\n\n\n\n## TL;DR\n\n`SJS` shows a significant increase in performance over both native `JSON.stringify` and `fast-json-stringify`.\nFor some use cases (dealing with long text), it performs **21000%** faster than both native and `fast-json-stringify`.\n\n**NOTE:** Support for undefined properties has been added from **1.0.1**. `SJS` is now production ready.\n\nCheckout [benchmarks](benchmark.md).\n\n## Installation\n\n`SJS` is fully compatible with both Node.js and the browser 🎉🎉\n\nNode:\n```bash\nnpm install slow-json-stringify\n```\n\nOn the browser:\n```html\n\u003cscript src=\"https://unpkg.com/slow-json-stringify/dist/sjs.umd.js\"\u003e\u003c/script\u003e\n```\n\n## How it works\n\nWhy `SJS` is the fastest stringifier?\nThe traditional approach consists in serializing every property taken singularly.\n`SJS` uses a different approach to serialization.\n\n**Preparation:**\n- A schema is provided\n- The schema is stringified\n- A templated string is built with the provided schema.\n\n**Serialization:**\n- Object values are inserted in the already built template.\n\nIt is faster simply because it performs a lot less work.\n\n## Caveats\n\n`SJS` require some setup work if compared to native `JSON.stringify`.\nBut, if you are dealing with json with a fixed structure `SJS` will save you a ton of time.\nEspecially when the payload grows. And incredibly when serializing json with long text inside (think of a blog article or a product description.\nMoreover, `SJS` makes possible the serialization of types that are not natively supported by `JSON.stringify` thanks to [custom serializers](#serializers).\n\n**note:** `SJS` won't perform any escaping as you usually won't need it in small payloads. If you are working with big text, it could be of very little effort to store in your db an already escaped text.\n\nHowever, `SJS` provides a little utility for your escaping needs.\n`escape` uses a default regex if no additional regex is provided.\n\n**default regex string:** \n```javascript\n/\\n|\\r|\\t|\\\"|\\\\/gm\n``` \n\nYou can use `escape` like the following:\n\n```javascript\nconst { escape } = require('slow-json-stringify');\n\n// If you don't pass any additional regex, a default one will be used.\nconst escaper = escape();\n\nescaper('This is \"funny\"'); // This is \\\"funny\\\"\n\n// You can pass any regex you want for your escaping strategy.\nconst customEscaper = escape(/\\\"/gm);\n\ncustomEscaper('This is \"funny\"'); // This is \\\"funny\\\"\n\n```\n\n## Benchmarks\n\nWe all know that there are three kinds of lies..\n\nLies, damned lies.. and benchmarks.\n\nRemember to test if `SJS` could be a real improvement for your use case.\nBecause there are times when the performance advantages with the added drawbacks could not be worth it.\n\n#### Running the benchmarks\n\nEvery benchmark is replicable on your own machine.\nTo run your tests:\n- Clone this repo.\n- Install dependencies.\n- `cd benchmark`.\n- Grant executable rights to `run.sh` script `chmod +x ./run.sh`.\n- Save benchmark results to file `./run.sh \u003e\u003e benchmark.md`\n\n#### Test machine\n\nThe benchmarks were performed on a Dell Xps 15 9550.\n- **cpu:** intel i7 6700HQ\n- **ram:** 16gb\n- **os:** Ubuntu 18.04\n\n#### Some numbers\n\nCheckout benchmarks [here](benchmark.md)\n\n## Usage\n\n#### Supported types\n\nThe schema creation happens thanks to the `attr` helper exported from the main bundle.\n\n```js\nconst { attr } = require('sjs');\n```\n\n```bash\nattr(type, serializer?)\n```\n\nThe `attr` helper natively supports the following types:\n- `string`\n- `number`\n- `boolean`\n- `null`\n- `array`, dynamic array with simple structure, in this scenario native `JSON.stringify` will be used. As there are no real performance advantages.\n\nThe serialization of any other type is possible thanks to [custom serializers](#serializers).\n\n#### Defining a schema\n\nFor a correct stringification of your json payload, a correct schema is mandatory.\nDefining a schema is pretty handy and not verbose at all.\n\n```javascript\nconst { sjs } = require('slow-json-stringify');\n\n// schema definition\nconst stringify = sjs({\n  a: attr('string'),\n  b: attr('number'),\n  c: attr('boolean'),\n});\n\n// then you can stringify anything with that structure.\nstringify({\n  a: 'world',\n  b: 42,\n  c: true,\n});\n\n// {\"a\":\"world\",\"b\":42,\"c\":true}\n\n```\n\n#### Defining schema with simple array\n\nWhen stringifying simple array `JSON.stringify` will be internally used.\n\n```javascript\nconst { sjs } = require('slow-json-stringify');\n\n// schema definition\nconst stringify = sjs({\n  a: attr('array'),\n});\n\n// then you can stringify anything with that structure.\nstringify({\n  a: [1, 2, 3, true, 'world'],\n});\n\n// {\"a\":[1,2,3,true,\"world\"]}\n\n```\n\n#### Defining schema with complex array\n\nThe `attr` helper accepts an additional `sjs` schema for `array` properties.\n\n```javascript\nconst { sjs } = require('slow-json-stringify');\n\n// schema definition\nconst stringify = sjs({\n  a: attr('array', sjs({\n    b: array('string'),\n    c: array('number'),\n  }))\n});\n\n// then you can stringify anything with that structure.\nstringify({\n  a: [{\n    b: 'ciao1',\n    c: 1,\n  }, {\n    b: 'ciao2',\n    c: 2,\n  }, {\n    b: 'ciao3',\n    c: 3,\n  }, {\n    b: 'ciao4',\n    c: 4, \n  }],\n});\n\n// {\"a\":[{\"b\":\"ciao1\",\"c\":1},{\"b\":\"ciao2\",\"c\":2},{\"b\":\"ciao3\",\"c\":3},{\"b\":\"ciao4\",\"c\":4}]}\n\n```\n\n#### Defining schema with nested objects\n\nDefining schemas with nested objects is pretty straightforward.\n\n```javascript\nconst { sjs } = require('slow-json-stringify');\n\n// schema definition\nconst stringify = sjs({\n  a: {\n    b: {\n      c: attr('string'),\n    },\n  },\n  d: {\n    e: attr('number'),\n  },\n});\n\nstringify({\n  a: {\n    b: {\n      c: 'hello',\n    },\n  },\n  d: {\n    e: 42,\n  },\n});\n\n// {\"a\":{\"b\":{\"c\":\"hello\"}},\"d\":{\"e\":42}}\n\n```\n\n## Serializers\n\nThe `attr` helper accepts a serializer function. The serializer function gets invoked with the real value that should be stringified. \n\n```bash\nserializer(rawValue)\n```\n\nProperty serializers are useful to perform custom serialization on any provide type not natively supported even by `JSON.stringify` (Dates, regular expressions).\nThey can be used also to skip property serializarion when returning `undefined`.\n\n```javascript\nconst { sjs } = require('slow-json-stringify');\n\n// schema definition\nconst stringify = sjs({\n  a: attr('number', (value) =\u003e {\n    if (value \u003e 10) {\n      return value;\n    }\n\n    return undefined;\n  })\n});\n\nstringify({ a: 20 });\n// {\"a\":20}\n\nstringify({ a: 5 });\n// {}\n\n```\n\n**use case:** Serialization of any type.\n\n```js\n// DATES\nconst stringify = sjs({\n  date: attr('string', (value) =\u003e value.toLocaleString()),\n});\n\n// REGEXP\nconst stringify = sjs({\n  regexp: attr('string', (value) =\u003e value.toString()),\n});\n```\n\n**use case:** Customize payloads based on access rights.\n\n```js\nconst stringify = sjs({\n  publicProp: attr('string'),\n  restrictedProp: attr('string', (value) =\u003e isAdmin ? value : undefined),\n});\n```\n\n**use case:** Value formatting\n\n```js\nconst stringify = sjs({\n  prop: attr('string', (value) =\u003e value.toUpperCase()),\n});\n```\n\n## API\n\n#### sjs\n| param  | type    | required                           | default   | spec                                                |\n|--------|---------|------------------------------------|-----------|-----------------------------------------------------|\n| schema | object  | yes                                | undefined | Schema that defines the stringification behavior.   |\n\n#### attr\n| param      | type     | required                           | default   | spec                                                   |\n|------------|----------|------------------------------------|-----------|--------------------------------------------------------|\n| type       | string   | yes                                | undefined | Type of the property.                                  |\n| serializer | function | no                                 | identity  | Function used for serializing / validating properties. |\n\n#### escape\n| param | type               | required                           | default                   | spec                                                |\n|-------|--------------------|------------------------------------|---------------------------|-----------------------------------------------------|\n| regex | Regular Expression | no                                 | default regex | regex used to escape text                           |\n\n## License\n\nMIT.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flucagez%2Fslow-json-stringify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flucagez%2Fslow-json-stringify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flucagez%2Fslow-json-stringify/lists"}