LRU-based memoizer for Intl constructors.
npm install @httpx/memo-intlLRU-based memoizer for Intl.NumberFormat,Intl.DateFormat and other Intl constructors.
Speeds up Intl operations up to 30x.









``bash`
$ npm install @httpx/memo-intl
$ yarn add @httpx/memo-intl
$ pnpm add @httpx/memo-intl
- 👉 Don't re-create the same Intl instance for the same options (memoized).
- 👉 Keep the Intl api untouched. Just replace new Intl.NumberFormat by MIntl.NumberFormat...
- 👉 Up to 30x faster than non-memoized Intl constructors.
- 👉 Decrease memory usage, unwanted memory leaks and garbage collection pressure.
- 👉 Max out 50 cache instances by default with @httpx/lru.
- 👉 Lightweight. Node, bun, browser and edge support.
👉 Official website or Github Readme
`typescript
import { MIntl } from "@httpx/memo-intl";
// Notice: new Intl.NumberFormat vs MIntl.NumberFormat`
const formattedPrice = MIntl.NumberFormat("fr-FR", {
style: "currency",
currency: "EUR",
notation: "compact",
minimumFractionDigits: 2,
maximumFractionDigits: 2,
}).format(row.price);
`typescript
import { MIntl } from "@httpx/memo-intl";
// Notice: new Intl.DateTimeFormat vs MIntl.DateTimeFormat
const formatter = MIntl.DateTimeFormat("fr-FR", {
dateStyle: "full",
timeStyle: "full",
timeZone: "UTC",
});
const date = Date.parse("2024-05-29T07:42:43.230Z");
expect(formatter.format(date)).toBe(
"mercredi 29 mai 2024 à 07:42:43 temps universel coordonné"
);
expectTypeOf(formatter).toEqualTypeOf
``
`typescript
import { MIntl } from "@httpx/memo-intl";
const locale = MIntl.Locale("fr-FR", { caseFirst: "lower" });
console.log(locale.language); // "fr"
`
`typescript
import { MIntl } from "@httpx/memo-intl";
const collator = MIntl.Collator("de", { sensitivity: "base" });
console.log(["Z", "a", "z", "ä"].sort(collator.compare));
`
`typescript
import { MIntl } from "@httpx/memo-intl";
const rtf = MIntl.RelativeTimeFormat("en", { style: "short" });
console.log(rtf.format(3, "month")); // e.g. "in 3 mos."
`
`typescript
import { MIntl } from "@httpx/memo-intl";
const listFormatter = MIntl.ListFormat("en", {
style: "long",
type: "conjunction",
});
console.log(listFormatter.format(["Red", "Green", "Blue"]));
`
`typescript
import { MIntl } from "@httpx/memo-intl";
const pr = MIntl.PluralRules("en-US", { type: "cardinal" });
console.log(pr.select(1)); // "one"
`
`typescript
import { MIntl } from "@httpx/memo-intl";
const segmenter = MIntl.Segmenter("fr", { granularity: "word" });
const result = segmenter.segment("Bonjour le monde");
console.log([...result].map(({ segment }) => segment));
`
You can clear the cache or check the cache stats.
`typescript
// Clear the cache
MIntl.cache.clear();
// Check cache stats
console.log(MIntl.cache.stats());
`
Performance is monitored with codspeed.io.

See bench for details.
`
RUN v4.0.15 /home/sebastien/github/httpx/packages/memo-intl
✓ bench/m-intl.number-formatter.bench.ts > MIntl NumberFormatter benchmarks (1000 instances) 1294ms
name hz min max mean p75 p99 p995 p999 rme samples
· With memoization MIntl.NumberFormatter() 1,505.36 0.5185 1.5463 0.6643 0.6942 1.0228 1.1927 1.5463 ±0.99% 753new Intl.NumberFormatter()
· Without memoization 45.3186 21.1337 23.1010 22.0660 22.3082 23.1010 23.1010 23.1010 ±0.91% 23
✓ bench/m-intl.date-formatter.bench.ts > MIntl DateFormatter benchmarks (1000 instances) 1509ms
name hz min max mean p75 p99 p995 p999 rme samples
· With memoization MIntl.DateFormatter() 639.68 1.2663 2.6546 1.5633 1.6006 2.2871 2.2935 2.6546 ±1.31% 320new Intl.DateFormatter()
· Without memoization 17.4417 52.7808 70.5025 57.3339 55.9290 70.5025 70.5025 70.5025 ±7.30% 9
✓ bench/m-intl.relative-time-format.bench.ts > MIntl RelativeTimeFormat benchmarks (1000 instances) 1246ms
name hz min max mean p75 p99 p995 p999 rme samples
· With memoization MIntl.RelativeTimeFormat() 1,905.42 0.4204 1.0122 0.5248 0.5442 0.7369 0.8688 1.0122 ±0.74% 953new Intl.RelativeTimeFormat()
· Without memoization 97.2481 7.6225 30.8928 10.2830 10.0394 30.8928 30.8928 30.8928 ±11.33% 49
✓ bench/m-intl.locale.bench.ts > MIntl Locale benchmarks (1000 instances) 1226ms
name hz min max mean p75 p99 p995 p999 rme samples
· With memoization MIntl.Locale() 6,327.65 0.1240 0.6766 0.1580 0.1621 0.2588 0.2956 0.4056 ±0.57% 3164new Intl.Locale()
· Without memoization 284.81 2.7692 9.1417 3.5111 3.3905 8.9251 9.1417 9.1417 ±4.86% 143
BENCH Summary
With memoization MIntl.DateFormatter() - bench/m-intl.date-formatter.bench.ts > MIntl DateFormatter benchmarks (1000 instances)new Intl.DateFormatter()
36.68x faster than Without memoization
With memoization MIntl.Locale() - bench/m-intl.locale.bench.ts > MIntl Locale benchmarks (1000 instances)new Intl.Locale()
22.22x faster than Without memoization
With memoization MIntl.NumberFormatter() - bench/m-intl.number-formatter.bench.ts > MIntl NumberFormatter benchmarks (1000 instances)new Intl.NumberFormatter()
33.22x faster than Without memoization
With memoization MIntl.RelativeTimeFormat() - bench/m-intl.relative-time-format.bench.ts > MIntl RelativeTimeFormat benchmarks (1000 instances)new Intl.RelativeTimeFormat()
19.59x faster than Without memoization `
Bundle size is tracked by a size-limit configuration
| Scenario | Size with deps (compressed) |
| ----------------------------------------- | --------------------------: |
| import { MIntl } from '@httpx/memo-intl' | ~ 790B |
> Note that per-se the library weights less than 300 bytes, the size limit accounts for the @httpx/lru dependency.
> For CJS usage (not recommended) track the size on bundlephobia.
| Level | CI | Description |
| ------------ | --- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Node | ✅ | CI for 20.x, 22.x, 24.x & 25.x. |
| Browser | ✅ | Tested with latest chrome (vitest/playwright) |
| Browserslist | ✅ | > 95% on 01/2025. defaults, chrome >= 96, firefox >= 105, edge >= 113, safari >= 15, ios >= 15, opera >= 103, not dead |
| Bun | ✅ | Tested with latest (at time of writing >= 1.3.3) |
| Edge | ✅ | Ensured on CI with @vercel/edge-runtime. |
| Cloudflare | ✅ | Ensured with @cloudflare/vitest-pool-workers (see wrangler.toml |
| Typescript | ✅ | TS 5.0 + / are-the-type-wrong checks on CI. |
| ES2022 | ✅ | Dist files checked with es-check |
| Performance | ✅ | Monitored with with codspeed.io |
> For _older_ browsers: most frontend frameworks can transpile the library (ie: nextjs...)
Contributions are warmly appreciated. Have a look to the CONTRIBUTING document.
If my OSS work brightens your day, let's take it to new heights together!
Sponsor>), coffee>),
or star – any gesture of support fuels my passion to improve. Thanks for being awesome! 🙏❤️
![]() | |
JetBrains | Embie.be |
MIT © belgattitude and contributors.