{"id":13528285,"url":"https://github.com/msgpack/msgpack-javascript","last_synced_at":"2025-05-12T15:33:04.677Z","repository":{"id":1837451,"uuid":"2761854","full_name":"msgpack/msgpack-javascript","owner":"msgpack","description":"@msgpack/msgpack - MessagePack for JavaScript / msgpack.org[ECMA-262/JavaScript/TypeScript]","archived":false,"fork":false,"pushed_at":"2025-03-12T11:11:35.000Z","size":3563,"stargazers_count":1384,"open_issues_count":19,"forks_count":170,"subscribers_count":28,"default_branch":"main","last_synced_at":"2025-04-23T17:19:32.277Z","etag":null,"topics":["deno-library","javascript-library","messagepack","msgpack","serialization-library","typescript-library","universal-javascript"],"latest_commit_sha":null,"homepage":"https://msgpack.org/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"Iakh/d-art-containers","license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/msgpack.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,"zenodo":null}},"created_at":"2011-11-12T14:13:11.000Z","updated_at":"2025-04-22T23:56:12.000Z","dependencies_parsed_at":"2024-09-24T23:01:09.611Z","dependency_job_id":"caeb792d-df07-4322-8b6a-cb059f821582","html_url":"https://github.com/msgpack/msgpack-javascript","commit_stats":{"total_commits":777,"total_committers":19,"mean_commits":40.89473684210526,"dds":0.157014157014157,"last_synced_commit":"6e22414e88afb165b0e29c797272e6e9aa0655b1"},"previous_names":[],"tags_count":71,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msgpack%2Fmsgpack-javascript","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msgpack%2Fmsgpack-javascript/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msgpack%2Fmsgpack-javascript/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msgpack%2Fmsgpack-javascript/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/msgpack","download_url":"https://codeload.github.com/msgpack/msgpack-javascript/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253766007,"owners_count":21960832,"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":["deno-library","javascript-library","messagepack","msgpack","serialization-library","typescript-library","universal-javascript"],"created_at":"2024-08-01T06:02:23.701Z","updated_at":"2025-05-12T15:33:04.597Z","avatar_url":"https://github.com/msgpack.png","language":"TypeScript","readme":"# MessagePack for ECMA-262/JavaScript/TypeScript  \u003c!-- omit in toc --\u003e\n\n[![npm version](https://img.shields.io/npm/v/@msgpack/msgpack.svg)](https://www.npmjs.com/package/@msgpack/msgpack) ![CI](https://github.com/msgpack/msgpack-javascript/workflows/CI/badge.svg) [![codecov](https://codecov.io/gh/msgpack/msgpack-javascript/branch/master/graphs/badge.svg)](https://codecov.io/gh/msgpack/msgpack-javascript) [![minzip](https://badgen.net/bundlephobia/minzip/@msgpack/msgpack)](https://bundlephobia.com/result?p=@msgpack/msgpack) [![tree-shaking](https://badgen.net/bundlephobia/tree-shaking/@msgpack/msgpack)](https://bundlephobia.com/result?p=@msgpack/msgpack)\n\nThis library is an implementation of **MessagePack** for TypeScript and JavaScript, providing a compact and efficient binary serialization format. Learn more about MessagePack at:\n\nhttps://msgpack.org/\n\nThis library serves as a comprehensive reference implementation of MessagePack for JavaScript with a focus on accuracy, compatibility, interoperability, and performance.\n\nAdditionally, this is also a universal JavaScript library. It is compatible not only with browsers, but with Node.js or other JavaScript engines that implement ES2015+ standards. As it is written in [TypeScript](https://www.typescriptlang.org/), this library bundles up-to-date type definition files (`d.ts`).\n\n*Note that this is the second edition of \"MessagePack for JavaScript\". The first edition, which was implemented in ES5 and never released to npmjs.com, is tagged as [`classic`](https://github.com/msgpack/msgpack-javascript/tree/classic).\n\n## Synopsis\n\n```typescript\nimport { deepStrictEqual } from \"assert\";\nimport { encode, decode } from \"@msgpack/msgpack\";\n\nconst object = {\n  nil: null,\n  integer: 1,\n  float: Math.PI,\n  string: \"Hello, world!\",\n  binary: Uint8Array.from([1, 2, 3]),\n  array: [10, 20, 30],\n  map: { foo: \"bar\" },\n  timestampExt: new Date(),\n};\n\nconst encoded: Uint8Array = encode(object);\n\ndeepStrictEqual(decode(encoded), object);\n```\n\n## Table of Contents\n\n- [Synopsis](#synopsis)\n- [Table of Contents](#table-of-contents)\n- [Install](#install)\n- [API](#api)\n  - [`encode(data: unknown, options?: EncoderOptions): Uint8Array`](#encodedata-unknown-options-encoderoptions-uint8array)\n    - [`EncoderOptions`](#encoderoptions)\n  - [`decode(buffer: ArrayLike\u003cnumber\u003e | BufferSource, options?: DecoderOptions): unknown`](#decodebuffer-arraylikenumber--buffersource-options-decoderoptions-unknown)\n    - [`DecoderOptions`](#decoderoptions)\n  - [`decodeMulti(buffer: ArrayLike\u003cnumber\u003e | BufferSource, options?: DecoderOptions): Generator\u003cunknown, void, unknown\u003e`](#decodemultibuffer-arraylikenumber--buffersource-options-decoderoptions-generatorunknown-void-unknown)\n  - [`decodeAsync(stream: ReadableStreamLike\u003cArrayLike\u003cnumber\u003e | BufferSource\u003e, options?: DecoderOptions): Promise\u003cunknown\u003e`](#decodeasyncstream-readablestreamlikearraylikenumber--buffersource-options-decoderoptions-promiseunknown)\n  - [`decodeArrayStream(stream: ReadableStreamLike\u003cArrayLike\u003cnumber\u003e | BufferSource\u003e, options?: DecoderOptions): AsyncIterable\u003cunknown\u003e`](#decodearraystreamstream-readablestreamlikearraylikenumber--buffersource-options-decoderoptions-asynciterableunknown)\n  - [`decodeMultiStream(stream: ReadableStreamLike\u003cArrayLike\u003cnumber\u003e | BufferSource\u003e, options?: DecoderOptions): AsyncIterable\u003cunknown\u003e`](#decodemultistreamstream-readablestreamlikearraylikenumber--buffersource-options-decoderoptions-asynciterableunknown)\n  - [Reusing Encoder and Decoder instances](#reusing-encoder-and-decoder-instances)\n- [Extension Types](#extension-types)\n  - [ExtensionCodec context](#extensioncodec-context)\n  - [Handling BigInt with ExtensionCodec](#handling-bigint-with-extensioncodec)\n  - [The temporal module as timestamp extensions](#the-temporal-module-as-timestamp-extensions)\n- [Faster way to decode a large array of floating point numbers](#faster-way-to-decode-a-large-array-of-floating-point-numbers)\n- [Decoding a Blob](#decoding-a-blob)\n- [MessagePack Specification](#messagepack-specification)\n  - [MessagePack Mapping Table](#messagepack-mapping-table)\n- [Prerequisites](#prerequisites)\n  - [ECMA-262](#ecma-262)\n  - [NodeJS](#nodejs)\n  - [TypeScript Compiler / Type Definitions](#typescript-compiler--type-definitions)\n- [Benchmark](#benchmark)\n- [Distribution](#distribution)\n  - [NPM / npmjs.com](#npm--npmjscom)\n  - [CDN / unpkg.com](#cdn--unpkgcom)\n- [Deno Support](#deno-support)\n- [Bun Support](#bun-support)\n- [Maintenance](#maintenance)\n  - [Testing](#testing)\n  - [Continuous Integration](#continuous-integration)\n  - [Release Engineering](#release-engineering)\n  - [Updating Dependencies](#updating-dependencies)\n- [License](#license)\n\n## Install\n\nThis library is published to `npmjs.com` as [@msgpack/msgpack](https://www.npmjs.com/package/@msgpack/msgpack).\n\n```shell\nnpm install @msgpack/msgpack\n```\n\n## API\n\n### `encode(data: unknown, options?: EncoderOptions): Uint8Array`\n\nIt encodes `data` into a single MessagePack-encoded object, and returns a byte array as `Uint8Array`. It throws errors if `data` is, or includes, a non-serializable object such as a `function` or a `symbol`.\n\nfor example:\n\n```typescript\nimport { encode } from \"@msgpack/msgpack\";\n\nconst encoded: Uint8Array = encode({ foo: \"bar\" });\nconsole.log(encoded);\n```\n\nIf you'd like to convert an `uint8array` to a NodeJS `Buffer`, use `Buffer.from(arrayBuffer, offset, length)` in order not to copy the underlying `ArrayBuffer`, while `Buffer.from(uint8array)` copies it:\n\n```typescript\nimport { encode } from \"@msgpack/msgpack\";\n\nconst encoded: Uint8Array = encode({ foo: \"bar\" });\n\n// `buffer` refers the same ArrayBuffer as `encoded`.\nconst buffer: Buffer = Buffer.from(encoded.buffer, encoded.byteOffset, encoded.byteLength);\nconsole.log(buffer);\n```\n\n#### `EncoderOptions`\n\n| Name                | Type           | Default                       |\n| ------------------- | -------------- | ----------------------------- |\n| extensionCodec      | ExtensionCodec | `ExtensionCodec.defaultCodec` |\n| context             | user-defined   | -                             |\n| useBigInt64         | boolean        | false                         |\n| maxDepth            | number         | `100`                         |\n| initialBufferSize   | number         | `2048`                        |\n| sortKeys            | boolean        | false                         |\n| forceFloat32        | boolean        | false                         |\n| forceIntegerToFloat | boolean        | false                         |\n| ignoreUndefined     | boolean        | false                         |\n\n### `decode(buffer: ArrayLike\u003cnumber\u003e | BufferSource, options?: DecoderOptions): unknown`\n\nIt decodes `buffer` that includes a MessagePack-encoded object, and returns the decoded object typed `unknown`.\n\n`buffer` must be an array of bytes, which is typically `Uint8Array` or `ArrayBuffer`. `BufferSource` is defined as `ArrayBuffer | ArrayBufferView`.\n\nThe `buffer` must include a single encoded object. If the `buffer` includes extra bytes after an object or the `buffer` is empty, it throws `RangeError`. To decode `buffer` that includes multiple encoded objects, use `decodeMulti()` or `decodeMultiStream()` (recommended) instead.\n\nfor example:\n\n```typescript\nimport { decode } from \"@msgpack/msgpack\";\n\nconst encoded: Uint8Array;\nconst object = decode(encoded);\nconsole.log(object);\n```\n\nNodeJS `Buffer` is also acceptable because it is a subclass of `Uint8Array`.\n\n#### `DecoderOptions`\n\n| Name            | Type                | Default                                        |\n| --------------- | ------------------- | ---------------------------------------------- |\n| extensionCodec  | ExtensionCodec      | `ExtensionCodec.defaultCodec`                  |\n| context         | user-defined        | -                                              |\n| useBigInt64     | boolean             | false                                          |\n| rawStrings      | boolean             | false                                          |\n| maxStrLength    | number              | `4_294_967_295` (UINT32_MAX)                   |\n| maxBinLength    | number              | `4_294_967_295` (UINT32_MAX)                   |\n| maxArrayLength  | number              | `4_294_967_295` (UINT32_MAX)                   |\n| maxMapLength    | number              | `4_294_967_295` (UINT32_MAX)                   |\n| maxExtLength    | number              | `4_294_967_295` (UINT32_MAX)                   |\n| mapKeyConverter | MapKeyConverterType | throw exception if key is not string or number |\n\n`MapKeyConverterType` is defined as `(key: unknown) =\u003e string | number`.\n\nTo skip UTF-8 decoding of strings, `rawStrings` can be set to `true`. In this case, strings are decoded into `Uint8Array`.\n\nYou can use `max${Type}Length` to limit the length of each type decoded.\n\n### `decodeMulti(buffer: ArrayLike\u003cnumber\u003e | BufferSource, options?: DecoderOptions): Generator\u003cunknown, void, unknown\u003e`\n\nIt decodes `buffer` that includes multiple MessagePack-encoded objects, and returns decoded objects as a generator. See also `decodeMultiStream()`, which is an asynchronous variant of this function.\n\nThis function is not recommended to decode a MessagePack binary via I/O stream including sockets because it's synchronous. Instead, `decodeMultiStream()` decodes a binary stream asynchronously, typically spending less CPU and memory.\n\nfor example:\n\n```typescript\nimport { decode } from \"@msgpack/msgpack\";\n\nconst encoded: Uint8Array;\n\nfor (const object of decodeMulti(encoded)) {\n  console.log(object);\n}\n```\n\n### `decodeAsync(stream: ReadableStreamLike\u003cArrayLike\u003cnumber\u003e | BufferSource\u003e, options?: DecoderOptions): Promise\u003cunknown\u003e`\n\nIt decodes `stream`, where `ReadableStreamLike\u003cT\u003e` is defined as `ReadableStream\u003cT\u003e | AsyncIterable\u003cT\u003e`, in an async iterable of byte arrays, and returns decoded object as `unknown` type, wrapped in `Promise`.\n\nThis function works asynchronously, and might CPU resources more efficiently compared with synchronous `decode()`, because it doesn't wait for the completion of downloading.\n\nThis function is designed to work with whatwg `fetch()` like this:\n\n```typescript\nimport { decodeAsync } from \"@msgpack/msgpack\";\n\nconst MSGPACK_TYPE = \"application/x-msgpack\";\n\nconst response = await fetch(url);\nconst contentType = response.headers.get(\"Content-Type\");\nif (contentType \u0026\u0026 contentType.startsWith(MSGPACK_TYPE) \u0026\u0026 response.body != null) {\n  const object = await decodeAsync(response.body);\n  // do something with object\n} else { /* handle errors */ }\n```\n\n### `decodeArrayStream(stream: ReadableStreamLike\u003cArrayLike\u003cnumber\u003e | BufferSource\u003e, options?: DecoderOptions): AsyncIterable\u003cunknown\u003e`\n\nIt is alike to `decodeAsync()`, but only accepts a `stream` that includes an array of items, and emits a decoded item one by one.\n\nfor example:\n\n```typescript\nimport { decodeArrayStream } from \"@msgpack/msgpack\";\n\nconst stream: AsyncIterator\u003cUint8Array\u003e;\n\n// in an async function:\nfor await (const item of decodeArrayStream(stream)) {\n  console.log(item);\n}\n```\n\n### `decodeMultiStream(stream: ReadableStreamLike\u003cArrayLike\u003cnumber\u003e | BufferSource\u003e, options?: DecoderOptions): AsyncIterable\u003cunknown\u003e`\n\nIt is alike to `decodeAsync()` and `decodeArrayStream()`, but the input `stream` must consist of multiple MessagePack-encoded items. This is an asynchronous variant for `decodeMulti()`.\n\nIn other words, it could decode an unlimited stream and emits a decoded item one by one.\n\nfor example:\n\n```typescript\nimport { decodeMultiStream } from \"@msgpack/msgpack\";\n\nconst stream: AsyncIterator\u003cUint8Array\u003e;\n\n// in an async function:\nfor await (const item of decodeMultiStream(stream)) {\n  console.log(item);\n}\n```\n\nThis function is available since v2.4.0; previously it was called as `decodeStream()`.\n\n### Reusing Encoder and Decoder instances\n\n`Encoder` and `Decoder` classes are provided to have better performance by reusing instances:\n\n```typescript\nimport { deepStrictEqual } from \"assert\";\nimport { Encoder, Decoder } from \"@msgpack/msgpack\";\n\nconst encoder = new Encoder();\nconst decoder = new Decoder();\n\nconst encoded: Uint8Array = encoder.encode(object);\ndeepStrictEqual(decoder.decode(encoded), object);\n```\n\nAccording to our benchmark, reusing `Encoder` instance is about 20% faster\nthan `encode()` function, and reusing `Decoder` instance is about 2% faster\nthan `decode()` function. Note that the result should vary in environments\nand data structure.\n\n`Encoder` and `Decoder` take the same options as `encode()` and `decode()` respectively.\n\n## Extension Types\n\nTo handle [MessagePack Extension Types](https://github.com/msgpack/msgpack/blob/master/spec.md#extension-types), this library provides `ExtensionCodec` class.\n\nThis is an example to setup custom extension types that handles `Map` and `Set` classes in TypeScript:\n\n```typescript\nimport { encode, decode, ExtensionCodec } from \"@msgpack/msgpack\";\n\nconst extensionCodec = new ExtensionCodec();\n\n// Set\u003cT\u003e\nconst SET_EXT_TYPE = 0 // Any in 0-127\nextensionCodec.register({\n  type: SET_EXT_TYPE,\n  encode: (object: unknown): Uint8Array | null =\u003e {\n    if (object instanceof Set) {\n      return encode([...object], { extensionCodec });\n    } else {\n      return null;\n    }\n  },\n  decode: (data: Uint8Array) =\u003e {\n    const array = decode(data, { extensionCodec }) as Array\u003cunknown\u003e;\n    return new Set(array);\n  },\n});\n\n// Map\u003cK, V\u003e\nconst MAP_EXT_TYPE = 1; // Any in 0-127\nextensionCodec.register({\n  type: MAP_EXT_TYPE,\n  encode: (object: unknown): Uint8Array =\u003e {\n    if (object instanceof Map) {\n      return encode([...object], { extensionCodec });\n    } else {\n      return null;\n    }\n  },\n  decode: (data: Uint8Array) =\u003e {\n    const array = decode(data, { extensionCodec }) as Array\u003c[unknown, unknown]\u003e;\n    return new Map(array);\n  },\n});\n\nconst encoded = encode([new Set\u003cany\u003e(), new Map\u003cany, any\u003e()], { extensionCodec });\nconst decoded = decode(encoded, { extensionCodec });\n```\n\nEnsure you include your extensionCodec in any recursive encode and decode statements!\n\nNote that extension types for custom objects must be `[0, 127]`, while `[-1, -128]` is reserved for MessagePack itself.\n\n### ExtensionCodec context\n\nWhen you use an extension codec, it might be necessary to have encoding/decoding state to keep track of which objects got encoded/re-created. To do this, pass a `context` to the `EncoderOptions` and `DecoderOptions`:\n\n```typescript\nimport { encode, decode, ExtensionCodec } from \"@msgpack/msgpack\";\n\nclass MyContext {\n  track(object: any) { /*...*/ }\n}\n\nclass MyType { /* ... */ }\n\nconst extensionCodec = new ExtensionCodec\u003cMyContext\u003e();\n\n// MyType\nconst MYTYPE_EXT_TYPE = 0 // Any in 0-127\nextensionCodec.register({\n  type: MYTYPE_EXT_TYPE,\n  encode: (object, context) =\u003e {\n    if (object instanceof MyType) {\n      context.track(object); // \u003c-- like this\n      return encode(object.toJSON(), { extensionCodec, context });\n    } else {\n      return null;\n    }\n  },\n  decode: (data, extType, context) =\u003e {\n    const decoded = decode(data, { extensionCodec, context });\n    const my = new MyType(decoded);\n    context.track(my); // \u003c-- and like this\n    return my;\n  },\n});\n\n// and later\nimport { encode, decode } from \"@msgpack/msgpack\";\n\nconst context = new MyContext();\n\nconst encoded = = encode({myType: new MyType\u003cany\u003e()}, { extensionCodec, context });\nconst decoded = decode(encoded, { extensionCodec, context });\n```\n\n### Handling BigInt with ExtensionCodec\n\nThis library does not handle BigInt by default, but you have two options to handle it:\n\n* Set `useBigInt64: true` to map bigint to MessagePack's int64/uint64\n* Define a custom `ExtensionCodec` to map bigint to a MessagePack's extension type\n\n`useBigInt64: true` is the simplest way to handle bigint, but it has limitations:\n\n* A bigint is encoded in 8 byte binaries even if it's a small integer\n* A bigint must be smaller than the max value of the uint64 and larger than the min value of the int64. Otherwise the behavior is undefined.\n\nSo you might want to define a custom codec to handle bigint like this:\n\n```typescript\nimport { deepStrictEqual } from \"assert\";\nimport { encode, decode, ExtensionCodec } from \"@msgpack/msgpack\";\n\n// to define a custom codec:\nconst BIGINT_EXT_TYPE = 0; // Any in 0-127\nconst extensionCodec = new ExtensionCodec();\nextensionCodec.register({\n  type: BIGINT_EXT_TYPE,\n  encode(input: unknown): Uint8Array | null {\n    if (typeof input === \"bigint\") {\n      if (input \u003c= Number.MAX_SAFE_INTEGER \u0026\u0026 input \u003e= Number.MIN_SAFE_INTEGER) {\n        return encode(Number(input));\n      } else {\n        return encode(String(input));\n      }\n    } else {\n      return null;\n    }\n  },\n  decode(data: Uint8Array): bigint {\n    const val = decode(data);\n    if (!(typeof val === \"string\" || typeof val === \"number\")) {\n      throw new DecodeError(`unexpected BigInt source: ${val} (${typeof val})`);\n    }\n    return BigInt(val);\n  },\n});\n\n// to use it:\nconst value = BigInt(Number.MAX_SAFE_INTEGER) + BigInt(1);\nconst encoded: = encode(value, { extensionCodec });\ndeepStrictEqual(decode(encoded, { extensionCodec }), value);\n```\n\n### The temporal module as timestamp extensions\n\nThere is a proposal for a new date/time representations in JavaScript:\n\n* https://github.com/tc39/proposal-temporal\n\nThis library maps `Date` to the MessagePack timestamp extension by default, but you can re-map the temporal module (or [Temporal Polyfill](https://github.com/tc39/proposal-temporal/tree/main/polyfill)) to the timestamp extension like this:\n\n```typescript\nimport { Instant } from \"@std-proposal/temporal\";\nimport { deepStrictEqual } from \"assert\";\nimport {\n  encode,\n  decode,\n  ExtensionCodec,\n  EXT_TIMESTAMP,\n  encodeTimeSpecToTimestamp,\n  decodeTimestampToTimeSpec,\n} from \"@msgpack/msgpack\";\n\n// to define a custom codec\nconst extensionCodec = new ExtensionCodec();\nextensionCodec.register({\n  type: EXT_TIMESTAMP, // override the default behavior!\n  encode(input: unknown): Uint8Array | null {\n    if (input instanceof Instant) {\n      const sec = input.seconds;\n      const nsec = Number(input.nanoseconds - BigInt(sec) * BigInt(1e9));\n      return encodeTimeSpecToTimestamp({ sec, nsec });\n    } else {\n      return null;\n    }\n  },\n  decode(data: Uint8Array): Instant {\n    const timeSpec = decodeTimestampToTimeSpec(data);\n    const sec = BigInt(timeSpec.sec);\n    const nsec = BigInt(timeSpec.nsec);\n    return Instant.fromEpochNanoseconds(sec * BigInt(1e9) + nsec);\n  },\n});\n\n// to use it\nconst instant = Instant.fromEpochMilliseconds(Date.now());\nconst encoded = encode(instant, { extensionCodec });\nconst decoded = decode(encoded, { extensionCodec });\ndeepStrictEqual(decoded, instant);\n```\n\nThis will become default in this library with major-version increment, if the temporal module is standardized.\n\n## Faster way to decode a large array of floating point numbers\n\nIf there are large arrays of floating point numbers in your payload, there\nis a way to decode it faster: define a custom extension type for `Float#Array`\nwith alignment.\n\nAn extension type's `encode` method can return a function that takes a parameter\n`pos: number`. This parameter can be used to make alignment of the buffer,\nresulting decoding it much more performant.\n\nSee an example implementation for `Float32Array`:\n\n```typescript\nconst extensionCodec = new ExtensionCodec();\n\nconst EXT_TYPE_FLOAT32ARRAY = 0; // Any in 0-127\nextensionCodec.register({\n  type: EXT_TYPE_FLOAT32ARRAY,\n  encode: (object: unknown) =\u003e {\n    if (object instanceof Float32Array) {\n      return (pos: number) =\u003e {\n        const bpe = Float32Array.BYTES_PER_ELEMENT;\n        const padding = 1 + ((bpe - ((pos + 1) % bpe)) % bpe);\n        const data = new Uint8Array(object.buffer);\n        const result = new Uint8Array(padding + data.length);\n        result[0] = padding;\n        result.set(data, padding);\n        return result;\n      };\n    }\n    return null;\n  },\n  decode: (data: Uint8Array) =\u003e {\n    const padding = data[0]!;\n    const bpe = Float32Array.BYTES_PER_ELEMENT;\n    const offset = data.byteOffset + padding;\n    const length = data.byteLength - padding;\n    return new Float32Array(data.buffer, offset, length / bpe);\n  },\n});\n```\n\n## Decoding a Blob\n\n[`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) is a binary data container provided by browsers. To read its contents when it contains a MessagePack binary, you can use `Blob#arrayBuffer()` or `Blob#stream()`. `Blob#stream()`\nis recommended if your target platform support it. This is because streaming\ndecode should be faster for large objects. In both ways, you need to use\nasynchronous API.\n\n```typescript\nasync function decodeFromBlob(blob: Blob): unknown {\n  if (blob.stream) {\n    // Blob#stream(): ReadableStream\u003cUint8Array\u003e (recommended)\n    return await decodeAsync(blob.stream());\n  } else {\n    // Blob#arrayBuffer(): Promise\u003cArrayBuffer\u003e (if stream() is not available)\n    return decode(await blob.arrayBuffer());\n  }\n}\n```\n\n## MessagePack Specification\n\nThis library is compatible with the \"August 2017\" revision of MessagePack specification at the point where timestamp ext was added:\n\n* [x] str/bin separation, added at August 2013\n* [x] extension types, added at August 2013\n* [x] timestamp ext type, added at August 2017\n\nThe living specification is here:\n\nhttps://github.com/msgpack/msgpack\n\nNote that as of June 2019 there're no official \"version\" on the MessagePack specification. See https://github.com/msgpack/msgpack/issues/195 for the discussions.\n\n### MessagePack Mapping Table\n\nThe following table shows how JavaScript values are mapped to [MessagePack formats](https://github.com/msgpack/msgpack/blob/master/spec.md) and vice versa.\n\nThe mapping of integers varies on the setting of `useBigInt64`.\n\nThe default, `useBigInt64: false` is:\n\n| Source Value          | MessagePack Format   | Value Decoded         |\n| --------------------- | -------------------- | --------------------- |\n| null, undefined       | nil                  | null (*1)             |\n| boolean (true, false) | bool family          | boolean (true, false) |\n| number (53-bit int)   | int family           | number                |\n| number (64-bit float) | float family         | number                |\n| string                | str family           | string (*2)           |\n| ArrayBufferView       | bin family           | Uint8Array (*3)       |\n| Array                 | array family         | Array                 |\n| Object                | map family           | Object (*4)           |\n| Date                  | timestamp ext family | Date (*5)             |\n| bigint                | N/A                  | N/A (*6)              |\n\n* *1 Both `null` and `undefined` are mapped to `nil` (`0xC0`) type, and are decoded into `null`\n* *2 If you'd like to skip UTF-8 decoding of strings, set `rawStrings: true`. In this case, strings are decoded into `Uint8Array`.\n* *3 Any `ArrayBufferView`s including NodeJS's `Buffer` are mapped to `bin` family, and are decoded into `Uint8Array`\n* *4 In handling `Object`, it is regarded as `Record\u003cstring, unknown\u003e` in terms of TypeScript\n* *5 MessagePack timestamps may have nanoseconds, which will lost when it is decoded into JavaScript `Date`. This behavior can be overridden by registering `-1` for the extension codec.\n* *6 bigint is not supported in `useBigInt64: false` mode, but you can define an extension codec for it.\n\nIf you set `useBigInt64: true`, the following mapping is used:\n\n| Source Value                      | MessagePack Format   | Value Decoded         |\n| --------------------------------- | -------------------- | --------------------- |\n| null, undefined                   | nil                  | null                  |\n| boolean (true, false)             | bool family          | boolean (true, false) |\n| **number (32-bit int)**           | int family           | number                |\n| **number (except for the above)** | float family         | number                |\n| **bigint**                        | int64 / uint64       | bigint (*7)           |\n| string                            | str family           | string                |\n| ArrayBufferView                   | bin family           | Uint8Array            |\n| Array                             | array family         | Array                 |\n| Object                            | map family           | Object                |\n| Date                              | timestamp ext family | Date                  |\n\n\n* *7 If the bigint is larger than the max value of uint64 or smaller than the min value of int64, then the behavior is undefined.\n\n## Prerequisites\n\nThis is a universal JavaScript library that supports major browsers and NodeJS.\n\n### ECMA-262\n\n* ES2015 language features\n* ES2024 standard library, including:\n  * Typed arrays (ES2015)\n  * Async iterations (ES2018)\n  * Features added in ES2015-ES2022\n* whatwg encodings (`TextEncoder` and `TextDecoder`)\n\nES2022 standard library used in this library can be polyfilled with [core-js](https://github.com/zloirock/core-js).\n\nIE11 is no longer supported. If you'd like to use this library in IE11, use v2.x versions.\n\n### NodeJS\n\nNodeJS v18 is required.\n\n### TypeScript Compiler / Type Definitions\n\nThis module requires type definitions of `AsyncIterator`, `ArrayBufferLike`, whatwg streams, and so on. They are provided by `\"lib\": [\"ES2024\", \"DOM\"]` in `tsconfig.json`.\n\nRegarding the TypeScript compiler version, only the latest TypeScript is tested in development.\n\n## Benchmark\n\nRun-time performance is not the only reason to use MessagePack, but it's important to choose MessagePack libraries, so a benchmark suite is provided to monitor the performance of this library.\n\nV8's built-in JSON has been improved for years, esp. `JSON.parse()` is [significantly improved in V8/7.6](https://v8.dev/blog/v8-release-76), it is the fastest deserializer as of 2019, as the benchmark result bellow suggests.\n\nHowever, MessagePack can handles binary data effectively, actual performance depends on situations. Esp. streaming-decoding may be significantly faster than non-streaming decoding if it's effective.  You'd better take benchmark on your own use-case if performance matters.\n\nBenchmark on NodeJS/v22.13.1 (V8/12.4)\n\n| operation                                         |      op |   ms |   op/s |\n| ------------------------------------------------- | ------: | ---: | -----: |\n| buf = Buffer.from(JSON.stringify(obj));           | 1348700 | 5000 | 269740 |\n| obj = JSON.parse(buf.toString(\"utf-8\"));          | 1700300 | 5000 | 340060 |\n| buf = require(\"msgpack-lite\").encode(obj);        |  591300 | 5000 | 118260 |\n| obj = require(\"msgpack-lite\").decode(buf);        |  539500 | 5000 | 107900 |\n| buf = require(\"@msgpack/msgpack\").encode(obj);    | 1238700 | 5000 | 247740 |\n| obj = require(\"@msgpack/msgpack\").decode(buf);    | 1402000 | 5000 | 280400 |\n| buf = /* @msgpack/msgpack */ encoder.encode(obj); | 1379800 | 5000 | 275960 |\n| obj = /* @msgpack/msgpack */ decoder.decode(buf); | 1406100 | 5000 | 281220 |\n\nNote that `JSON` cases use `Buffer` to emulate I/O where a JavaScript string must be converted into a byte array encoded in UTF-8, whereas MessagePack modules deal with byte arrays.\n\n## Distribution\n\n### NPM / npmjs.com\n\nThe NPM package distributed in npmjs.com includes both ES2015+ and ES5 files:\n\n* `dist/` is compiled into ES2020 with CommomJS, provided for NodeJS v10\n* `dist.umd/` is compiled into ES5 with UMD\n  * `dist.umd/msgpack.min.js` - the minified file\n  * `dist.umd/msgpack.js` - the non-minified file\n* `dist.esm/` is compiled into ES2020 with ES modules, provided for webpack-like bundlers and NodeJS's ESM-mode\n\nIf you use NodeJS and/or webpack, their module resolvers use the suitable one automatically.\n\n### CDN / unpkg.com\n\nThis library is available via CDN:\n\n```html\n\u003cscript crossorigin src=\"https://unpkg.com/@msgpack/msgpack\"\u003e\u003c/script\u003e\n```\n\nIt loads `MessagePack` module to the global object.\n\n\n## Deno Support\n\nYou can use this module on Deno.\n\nSee `example/deno-*.ts` for examples.\n\n`deno.land/x` is not supported.\n\n## Bun Support\n\nYou can use this module on Bun.\n\n## Maintenance\n\n### Testing\n\nFor simple testing:\n\n```\nnpm run test\n```\n\n### Continuous Integration\n\nThis library uses GitHub Actions.\n\nTest matrix:\n\n* NodeJS\n  * v18 / v20 / v22\n* Browsers:\n  * Chrome, Firefox\n* Deno\n* Bun\n\n### Release Engineering\n\n```console\n# run tests on NodeJS, Chrome, and Firefox\nmake test-all\n\n# edit the changelog\ncode CHANGELOG.md\n\n# bump version\nnpm version patch|minor|major\n\n# run the publishing task\nmake publish\n```\n\n### Updating Dependencies\n\n```console\nnpm run update-dependencies\n```\n\n## License\n\nCopyright 2019 The MessagePack community.\n\nThis software uses the ISC license:\n\nhttps://opensource.org/licenses/ISC\n\nSee [LICENSE](./LICENSE) for details.\n","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmsgpack%2Fmsgpack-javascript","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmsgpack%2Fmsgpack-javascript","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmsgpack%2Fmsgpack-javascript/lists"}