{"id":47696141,"url":"https://github.com/sovereignbase/bytecodec","last_synced_at":"2026-04-02T16:26:32.112Z","repository":{"id":328495458,"uuid":"1115735500","full_name":"sovereignbase/bytecodec","owner":"sovereignbase","description":"JS/TS runtime-agnostic byte toolkit for UTF-8 strings, base64, base64url, JSON, normalization, compression, concatenation, and comparison.","archived":false,"fork":false,"pushed_at":"2026-03-28T10:31:03.000Z","size":425,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-03-28T12:34:01.334Z","etag":null,"topics":["arraybuffer","base64","base64url","browser","bun","bytes","cjs","compression","deno","edge","equals","esm","hex","json","node","sovereignbase","typescript","uint8array","utf8-string","z85"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@sovereignbase/bytecodec","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/sovereignbase.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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-13T12:55:16.000Z","updated_at":"2026-03-28T10:29:26.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/sovereignbase/bytecodec","commit_stats":null,"previous_names":["jortsupetterson/bytecodec","z-base/bytecodec","sovereignbase/bytecodec"],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/sovereignbase/bytecodec","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sovereignbase%2Fbytecodec","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sovereignbase%2Fbytecodec/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sovereignbase%2Fbytecodec/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sovereignbase%2Fbytecodec/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sovereignbase","download_url":"https://codeload.github.com/sovereignbase/bytecodec/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sovereignbase%2Fbytecodec/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31309865,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T12:59:32.332Z","status":"ssl_error","status_checked_at":"2026-04-02T12:54:48.875Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: 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":["arraybuffer","base64","base64url","browser","bun","bytes","cjs","compression","deno","edge","equals","esm","hex","json","node","sovereignbase","typescript","uint8array","utf8-string","z85"],"created_at":"2026-04-02T16:26:30.994Z","updated_at":"2026-04-02T16:26:32.086Z","avatar_url":"https://github.com/sovereignbase.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![npm version](https://img.shields.io/npm/v/@sovereignbase/bytecodec)](https://www.npmjs.com/package/@sovereignbase/bytecodec)\n[![CI](https://github.com/sovereignbase/bytecodec/actions/workflows/ci.yaml/badge.svg?branch=master)](https://github.com/sovereignbase/bytecodec/actions/workflows/ci.yaml)\n[![codecov](https://codecov.io/gh/sovereignbase/bytecodec/branch/master/graph/badge.svg)](https://codecov.io/gh/sovereignbase/bytecodec)\n[![license](https://img.shields.io/npm/l/@sovereignbase/bytecodec)](LICENSE)\n\n# bytecodec\n\nTyped JavaScript and TypeScript byte utilities for base64, base64url, hex, Z85, UTF-8 strings, unsigned BigInt conversion, JSON, gzip, concatenation, comparison, and byte-source normalization. The package ships tree-shakeable ESM plus CommonJS entry points and keeps the same API across Node, Bun, Deno, browsers, and edge runtimes.\n\n## Compatibility\n\n- Runtimes: Node, Bun, Deno, browsers, Cloudflare Workers, and edge runtimes.\n- Module formats: ESM by default, with CommonJS exports for `require()` consumers in Node and Bun.\n- Node and Bun runtime behavior: uses `Buffer` for base64 helpers and `node:zlib` for gzip.\n- Browser and edge gzip support requires `CompressionStream` and `DecompressionStream`.\n- TypeScript: bundled types.\n\n## Goals\n\n- Developer-friendly API for base64, base64url, hex, Z85, UTF-8, unsigned BigInt conversion, JSON, gzip, concat, equality, and byte normalization.\n- No runtime dependencies or bundler shims.\n- Tree-shakeable ESM by default with CommonJS compatibility and no side effects.\n- Returns copies for safety when normalizing inputs.\n- Consistent behavior across Node, browsers, and edge runtimes.\n\n## Installation\n\n```sh\nnpm install @sovereignbase/bytecodec\n# or\npnpm add @sovereignbase/bytecodec\n# or\nyarn add @sovereignbase/bytecodec\n# or\nbun add @sovereignbase/bytecodec\n# or\ndeno add jsr:@sovereignbase/bytecodec\n# or\nvlt install jsr:@sovereignbase/bytecodec\n```\n\n## Usage\n\n### Bytes wrapper\n\n```js\nimport { Bytes } from '@sovereignbase/bytecodec'\n\n// The `Bytes` convenience class wraps the same functions as static methods.\nconst encoded = Bytes.toBase64String(new Uint8Array([1, 2, 3])) // base64 string\n```\n\n### Base64\n\n```js\nimport { toBase64String, fromBase64String } from '@sovereignbase/bytecodec'\n\nconst bytes = new Uint8Array([104, 101, 108, 108, 111])\nconst encoded = toBase64String(bytes) // string of base64 chars\nconst decoded = fromBase64String(encoded) // Uint8Array\n```\n\n### CommonJS\n\n```js\nconst { toBase64String, fromBase64String } = require('@sovereignbase/bytecodec')\n\nconst encoded = toBase64String([104, 101, 108, 108, 111]) // string of base64 chars\nconst decoded = fromBase64String(encoded) // Uint8Array\n```\n\n### Base64URL\n\n```js\nimport {\n  toBase64UrlString,\n  fromBase64UrlString,\n} from '@sovereignbase/bytecodec'\n\nconst bytes = new Uint8Array([104, 101, 108, 108, 111])\nconst encoded = toBase64UrlString(bytes) // string of base64url chars\nconst decoded = fromBase64UrlString(encoded) // Uint8Array\n```\n\n### Hex\n\n```js\nimport { toHex, fromHex } from '@sovereignbase/bytecodec'\n\nconst bytes = new Uint8Array([222, 173, 190, 239])\nconst encoded = toHex(bytes) // \"deadbeef\"\nconst decoded = fromHex(encoded) // Uint8Array\n```\n\n### Z85\n\n```js\nimport { toZ85String, fromZ85String } from '@sovereignbase/bytecodec'\n\nconst bytes = new Uint8Array([0x86, 0x4f, 0xd2, 0x6f, 0xb5, 0x59, 0xf7, 0x5b])\nconst encoded = toZ85String(bytes) // \"HelloWorld\"\nconst decoded = fromZ85String(encoded) // Uint8Array\n```\n\nZ85 encodes 4 input bytes into 5 output characters, so `toZ85String()` requires a byte length divisible by 4 and `fromZ85String()` requires a string length divisible by 5.\n\n### UTF-8 strings\n\n```js\nimport { fromString, toString } from '@sovereignbase/bytecodec'\n\nconst textBytes = fromString('caffe and rockets') // Uint8Array\nconst text = toString(textBytes) // \"caffe and rockets\"\n```\n\n### BigInt\n\n```js\nimport { fromBigInt, toBigInt } from '@sovereignbase/bytecodec'\n\nconst bytes = fromBigInt(0x1234n) // Uint8Array([0x12, 0x34])\nconst value = toBigInt(bytes) // 0x1234n\n```\n\nBigInt helpers use unsigned big-endian encoding. `fromBigInt(0n)` returns an empty `Uint8Array`, because no byte width is implied.\nLeading zero bytes are not preserved, so the helpers model integers rather than fixed-width binary fields.\n\n### JSON\n\n```js\nimport { fromJSON, toJSON } from '@sovereignbase/bytecodec'\n\nconst jsonBytes = fromJSON({ ok: true, count: 3 }) // Uint8Array\nconst obj = toJSON(jsonBytes) // { ok: true, count: 3 }\n```\n\n### Compression\n\n```js\nimport { toCompressed, fromCompressed } from '@sovereignbase/bytecodec'\n\nconst compressed = await toCompressed(new Uint8Array([1, 2, 3])) // Uint8Array\nconst restored = await fromCompressed(compressed) // Uint8Array\n```\n\n### Normalization\n\n```js\nimport {\n  toUint8Array,\n  toArrayBuffer,\n  toBufferSource,\n} from '@sovereignbase/bytecodec'\n\nconst normalized = toUint8Array([1, 2, 3]) // Uint8Array\nconst copied = toArrayBuffer(normalized) // ArrayBuffer\nconst bufferSource = toBufferSource(normalized) // Uint8Array as BufferSource\n```\n\nAccepted byte inputs (`ByteSource`) are:\n\n- `ArrayBuffer`\n- `SharedArrayBuffer`\n- `ArrayBufferView`\n- `number[]`\n\n### Equality\n\n```js\nimport { equals } from '@sovereignbase/bytecodec'\n\nconst isSame = equals(new Uint8Array([1, 2, 3]), new Uint8Array([1, 2, 3])) // true | false\n```\n\n### Concatenating\n\n```js\nimport { concat } from '@sovereignbase/bytecodec'\n\nconst joined = concat([new Uint8Array([1, 2]), new Uint8Array([3, 4]), [5, 6]]) // Uint8Array\n```\n\n## Runtime behavior\n\n### Node\n\nUses `Buffer.from` for base64 helpers, `TextEncoder` and `TextDecoder` when available with `Buffer` fallback for UTF-8, and `node:zlib` for gzip.\n\n### Bun\n\nUses the same API shape as Node. ESM and CommonJS entry points are both exported.\n\n### Browsers / Edge runtimes\n\nUses `TextEncoder`, `TextDecoder`, `btoa`, and `atob`. Gzip uses `CompressionStream` and `DecompressionStream` when available.\n\n### Validation \u0026 errors\n\nValidation failures throw `BytecodecError` instances with a `code` string, for example `BASE64URL_INVALID_LENGTH`, `BIGINT_UNSIGNED_EXPECTED`, `HEX_INVALID_CHARACTER`, `Z85_INVALID_BLOCK`, `BASE64_DECODER_UNAVAILABLE`, `UTF8_DECODER_UNAVAILABLE`, and `GZIP_COMPRESSION_UNAVAILABLE`. Messages are prefixed with `{@sovereignbase/bytecodec}`.\n\n### Safety / copying semantics\n\n`toUint8Array`, `toArrayBuffer`, and `toBufferSource` always return copies. `concat` normalizes each input to a fresh `Uint8Array` before joining.\n\n## Tests\n\n`npm test` covers:\n\n- 75 unit tests\n- 7 integration tests\n- Node E2E: 23/23 passed in ESM and 23/23 passed in CommonJS\n- Bun E2E: 23/23 passed in ESM and 23/23 passed in CommonJS\n- Deno E2E: 23/23 passed in ESM\n- Cloudflare Workers E2E: 23/23 passed in ESM\n- Edge Runtime E2E: 23/23 passed in ESM\n- Browser E2E: 5/5 passed in Chromium, Firefox, WebKit, mobile-chrome, and mobile-safari\n- Coverage gate: 100% statements, branches, functions, and lines\n\n## Benchmarks\n\nLatest local `npm run bench` run on 2026-03-27 with Node `v22.14.0 (win32 x64)`:\n\n| Benchmark        | Result                    |\n| ---------------- | ------------------------- |\n| base64 encode    | 979,522 ops/s (51.0 ms)   |\n| base64 decode    | 1,825,737 ops/s (27.4 ms) |\n| base64url encode | 407,973 ops/s (122.6 ms)  |\n| base64url decode | 560,991 ops/s (89.1 ms)   |\n| hex encode       | 781,944 ops/s (63.9 ms)   |\n| hex decode       | 806,002 ops/s (62.0 ms)   |\n| z85 encode       | 170,125 ops/s (293.9 ms)  |\n| z85 decode       | 1,141,472 ops/s (43.8 ms) |\n| utf8 encode      | 1,241,977 ops/s (40.3 ms) |\n| utf8 decode      | 2,610,407 ops/s (19.2 ms) |\n| bigint encode    | 490,692 ops/s (101.9 ms)  |\n| bigint decode    | 428,938 ops/s (116.6 ms)  |\n| json encode      | 588,066 ops/s (34.0 ms)   |\n| json decode      | 603,058 ops/s (33.2 ms)   |\n| concat 3 buffers | 560,639 ops/s (89.2 ms)   |\n| toUint8Array     | 6,292,910 ops/s (31.8 ms) |\n| toArrayBuffer    | 677,822 ops/s (295.1 ms)  |\n| toBufferSource   | 7,465,472 ops/s (26.8 ms) |\n| equals same      | 2,217,064 ops/s (90.2 ms) |\n| equals diff      | 2,302,002 ops/s (86.9 ms) |\n| gzip compress    | 3,473 ops/s (115.2 ms)    |\n| gzip decompress  | 4,753 ops/s (84.2 ms)     |\n\nCommand: `npm run bench`\n\nResults vary by machine and Node version.\n\n## License\n\nApache-2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsovereignbase%2Fbytecodec","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsovereignbase%2Fbytecodec","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsovereignbase%2Fbytecodec/lists"}