@httpx/stable-hash
Version:
Create keys or hashes from javascript values, useful for memoization or cache key generation.
280 lines (209 loc) • 14.8 kB
Markdown
or hashes from javascript values, useful for memoization or cache key generation.
[](https://www.npmjs.com/package/@httpx/stable-hash)
[](https://github.com/belgattitude/httpx/blob/main/packages/stable-hash/CHANGELOG.md)
[](https://app.codecov.io/gh/belgattitude/httpx/tree/main/packages%2Fstable-hash)
[](https://github.com/belgattitude/httpx/blob/main/packages/stable-hash/.size-limit.cjs)
[](#compatibility)
[](#compatibility)
[](https://bundlephobia.com/package/@httpx/stable-hash@latest)
[](https://www.npmjs.com/package/@httpx/stable-hash)
[](https://github.com/belgattitude/httpx/blob/main/LICENSE)
```bash
$ npm install @httpx/stable-hash
$ yarn add @httpx/stable-hash
$ pnpm add @httpx/stable-hash
```
- 👉 Works with plain objects, dates, bigint, number, null, undefined and arrays.
- 🦄 Insensitive to object keys or array parameters order.
- 🙏 Properly error if it encounters an unsupported datatype.
- 📐 Lightweight (starts at [~500B](
- 🛡️ Tested on [node 18-22, browser, cloudflare workers and runtime/edge](
- 🗝️ Available in ESM and CJS formats.
👉 [Official website](https://belgattitude.github.io/httpx/stable-hash) or [Github Readme](https://github.com/belgattitude/httpx/tree/main/packages/stable-hash#readme)
- [x] [createStableKey](
- [x] [createStableKeyOrThrow](
- [x] [createStableHash](
- [x] [createStableHashOrThrow](
```typescript
import { createStableKey } from '@httpx/stable-hash'
const params = {
key8: 'a string',
key1: 1,
key3: true,
key2: [3, 2, 1],
key7: {
key2: true,
key1: new Date('2025-02-11T08:58:32.075Z'),
},
};
const result = createStableKey(params);
if (!result.success) {
throw result.error; // TypeError
}
const key = result.key;
// Key contains a json comptatible string with object keys sorted.
// By default it will sort arrays if they contains only strings or numbers
// including bigints.
// "{"key1":1,"key2":[1,2,3],"key3":true,"key7":{"key1":"2025-02-11T08:58:32.075Z","key2":true},"key8":"a string"}"
```
```typescript
import { createStableKeyOrThrow } from '@httpx/stable-hash'
const params = {
key8: 'a string',
key1: 1,
key3: true,
key2: [3, 2, 1],
key7: {
key2: true,
key1: new Date('2025-02-11T08:58:32.075Z'),
},
};
const key = createStableKeyOrThrow(params);
// Key contains a json comptatible string with object keys sorted.
// By default it will sort arrays if they contains only strings or numbers
// including bigints.
// "{"key1":1,"key2":[1,2,3],"key3":true,"key7":{"key1":"2025-02-11T08:58:32.075Z","key2":true},"key8":"a string"}"
```
```typescript
import { createStableHash } from '@httpx/stable-hash';
const value = {
key8: 'a string',
key1: 1,
key3: true,
key2: [3, 2, 1],
key7: {
key2: true,
key1: new Date('2025-02-11T08:58:32.075Z'),
},
};
const result = await createStableHash(value, {
// By default SHA-256 is used (SHA-512 available)
algorithm: 'SHA-256',
// By default the hash is encoded in hexadecimal
encoding: 'hexa',
});
if (!result.success) {
throw result.error;
}
const hash = result.hash;
// -> 'fb17a6300efcf62ae80708e2a672aee581b7f0dd7c6a9a7a748218846c679394'
```
```typescript
import { createStableHashOrThrow } from '@httpx/stable-hash';
const params = {
key8: 'a string',
key1: 1,
key3: true,
key2: [3, 2, 1],
key7: {
key2: true,
key1: new Date('2025-02-11T08:58:32.075Z'),
},
};
try {
const hash = await createStableHashOrThrow(params, {
// By default SHA-256 is used (SHA-512 available)
algorithm: 'SHA-256',
// By default the hash is encoded in hexadecimal
encoding: 'hexa',
});
// -> 'fb17a6300efcf62ae80708e2a672aee581b7f0dd7c6a9a7a748218846c679394'
} catch (e) {
// TypeError in case of an unserializable data type
}
```
- [x] [stable-hash](https://github.com/shuding/stable-hash). Fastest alternative. Might swallow errors though.
Performance is monitored with [codspeed.io](https://codspeed.io/belgattitude/httpx).
[](https://codspeed.io/belgattitude/httpx)
See [bench](https://github.com/belgattitude/httpx/blob/main/packages/stable-hash/bench) for details.
Bundle size is tracked by a [size-limit configuration](https://github.com/belgattitude/httpx/blob/main/packages/stable-hash/.size-limit.ts)
| Scenario | Size with deps (compressed) |
|---------------------------------------------------------------|----------------------------:|
| `import { createStableKeyOrThrow } from '@httpx/stable-hash' | ~ 480B |
| `import { createStableKey } from '@httpx/stable-hash' | ~ 520B |
| `import { createStableHashOrThrow } from '@httpx/stable-hash' | ~ 650B |
| `import { createStableHash } from '@httpx/stable-hash' | ~ 695B |
| Level | CI | Description |
|--------------|----|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Node | ✅ | CI for 20.x & 22.x. |
| Browser | ✅ | Tested with latest chrome (vitest/playwright) |
| Browserslist | ✅ | [> 95%](https://browserslist.dev/?q=ZGVmYXVsdHMsIGNocm9tZSA%2BPSA5NiwgZmlyZWZveCA%2BPSAxMDUsIGVkZ2UgPj0gMTEzLCBzYWZhcmkgPj0gMTUsIGlvcyA%2BPSAxNSwgb3BlcmEgPj0gMTAzLCBub3QgZGVhZA%3D%3D) on 01/2025. [defaults, chrome >= 96, firefox >= 105, edge >= 113, safari >= 15, ios >= 15, opera >= 103, not dead](https://github.com/belgattitude/httpx/blob/main/packages/stable-hash/.browserslistrc) |
| Edge | ✅ | Ensured on CI with [@vercel/edge-runtime](https://github.com/vercel/edge-runtime). |
| Cloudflare | ✅ | Ensured with @cloudflare/vitest-pool-workers (see [wrangler.toml](https://github.com/belgattitude/httpx/blob/main/devtools/vitest/wrangler.toml) |
| Typescript | ✅ | TS 5.0 + / [are-the-type-wrong](https://github.com/arethetypeswrong/arethetypeswrong.github.io) checks on CI. |
| ES2022 | ✅ | Dist files checked with [es-check](https://github.com/yowainwright/es-check) |
| Performance | ✅ | Monitored with with [codspeed.io](https://codspeed.io/belgattitude/httpx) |
> For _older_ browsers: most frontend frameworks can transpile the library (ie: [nextjs](https://nextjs.org/docs/app/api-reference/next-config-js/transpilePackages)...)
## Benchmarks
> Performance is continuously monitored thanks to [codspeed.io](https://codspeed.io/belgattitude/httpx).
>
> [](https://codspeed.io/belgattitude/httpx)
```
RUN v3.0.5 /home/sebastien/github/httpx/packages/stable-hash
✓ bench/compare.bench.ts > Comparison 6441ms
name hz min max mean p75 p99 p995 p999 rme samples
· @httpx/stable-hash 294,773.22 0.0030 0.5363 0.0034 0.0032 0.0071 0.0094 0.0151 ±0.37% 147387 slowest
· stable-hash 13,291,407.61 0.0001 0.0766 0.0001 0.0001 0.0001 0.0001 0.0003 ±0.06% 6645705 fastest
· @tanstack/query-core (hashKey) 295,851.66 0.0031 0.4376 0.0034 0.0033 0.0042 0.0059 0.0076 ±0.50% 147926
✓ bench/create-stable-hash.bench.ts > createStableHashOrThrow 1228ms
name hz min max mean p75 p99 p995 p999 rme samples
· createStableHashOrThrow with array sorting 29,048.08 0.0263 0.2879 0.0344 0.0336 0.0729 0.1158 0.1718 ±0.49% 14525
· createStableHashOrThrow without array sorting 32,139.11 0.0245 0.9538 0.0311 0.0307 0.0459 0.0712 0.1496 ±0.55% 16070 fastest
✓ bench/create-stable-key.bench.ts > createStableKeyOrThrow 1403ms
name hz min max mean p75 p99 p995 p999 rme samples
· createStableKeyOrThrow with array sorting 203,266.13 0.0044 0.4635 0.0049 0.0048 0.0087 0.0091 0.0146 ±0.37% 101639
· createStableKeyOrThrow without array sorting 283,858.83 0.0031 0.8852 0.0035 0.0034 0.0073 0.0095 0.0149 ±0.46% 141930 fastest
BENCH Summary
stable-hash - bench/compare.bench.ts > Comparison
44.93x faster than @tanstack/query-core (hashKey)
45.09x faster than @httpx/stable-hash
createStableHashOrThrow without array sorting - bench/create-stable-hash.bench.ts > createStableHashOrThrow
1.11x faster than createStableHashOrThrow with array sorting
createStableKeyOrThrow without array sorting - bench/create-stable-key.bench.ts > createStableKeyOrThrow
1.40x faster than createStableKeyOrThrow with array sorting
```
> See [benchmark file](https://github.com/belgattitude/httpx/blob/main/packages/stable-hash/bench) for details.
## Contributors
Contributions are warmly appreciated. Have a look to the [CONTRIBUTING](https://github.com/belgattitude/httpx/blob/main/CONTRIBUTING.md) document.
## Sponsors
If my OSS work brightens your day, let's take it to new heights together!
[Sponsor](<[sponsorship](https://github.com/sponsors/belgattitude)>), [coffee](<(https://ko-fi.com/belgattitude)>),
or star – any gesture of support fuels my passion to improve. Thanks for being awesome! 🙏❤️
### Special thanks to
<table>
<tr>
<td>
<a href="https://www.jetbrains.com/?ref=belgattitude" target="_blank">
<img width="65" src="https://asset.brandfetch.io/idarKiKkI-/id53SttZhi.jpeg" alt="Jetbrains logo" />
</a>
</td>
<td>
<a href="https://www.embie.be/?ref=belgattitude" target="_blank">
<img width="65" src="https://avatars.githubusercontent.com/u/98402122?s=200&v=4" alt="Jetbrains logo" />
</a>
</td>
</tr>
<tr>
<td align="center">
<a href="https://www.jetbrains.com/?ref=belgattitude" target="_blank">JetBrains</a>
</td>
<td align="center">
<a href="https://www.embie.be/?ref=belgattitude" target="_blank">Embie.be</a>
</td>
</tr>
</table>
MIT © [Sébastien Vanvelthem](https://github.com/belgattitude) and contributors.
Create keys