Getting started · Formatting · Parsing · Diagnostics · Custom codecs · Bundle size
Check support when your application offers optional presentations or runs across different environments. Use supports(spec) to choose a fallback and resolve(spec) to explain invalid options, missing runtime features, or effective defaults. You do not need a support check before every call with a known, valid specification.
Check the operation you intend to use: formatter.supports(spec) checks display, while parser.supports(spec) checks parsing. A format can support display without parsing; localized durations are one example. Formatting resolutions always report capabilities.parse: false, so use the parser to decide whether a field can accept that presentation.
Use supports() when you can choose an alternative presentation. For example, a duration label can use localized words where available and elapsed time elsewhere:
import { formatter } from "@neutrium/formatter";
function durationLabel(seconds: number): string
{
const localized = { kind: "duration", presentation: "localized", style: "long" } as const;
if (formatter.supports(localized))
{
return formatter.format(seconds, localized);
}
return formatter.format(seconds, { kind: "duration", presentation: "elapsed" });
}
durationLabel(3661); // "1 hour, 1 minute, 1 second", or "1:01:01" without Intl.DurationFormat
Use resolve() when you need to explain a rejected configuration or the defaults that will be applied. Currency precision, for example, varies by currency:
import { formatter } from "@neutrium/formatter";
function currencyPrecisionHelp(currency: string): string
{
const result = formatter.resolve({ kind: "currency", currency });
if (!result.supported)
{
return `Currency display unavailable: ${result.error.message}`;
}
const digits = result.intl?.resolvedOptions.maximumFractionDigits;
return digits === undefined ? "Precision is automatic." : `Amounts display up to ${digits} decimal places.`;
}
currencyPrecisionHelp("USD"); // "Amounts display up to 2 decimal places."
currencyPrecisionHelp("JPY"); // "Amounts display up to 0 decimal places."
To offer range display for a dynamically selected codec, check resolution.capabilities.range. rangeImplementation explains how supported ranges are rendered: native, conditional, fallback, or custom. conditional means some values need the wrapper fallback, such as parenthesized negatives. It does not mean the range is unavailable.
Check result.supported before reading effective options or capabilities. When it is false, use result.error to explain the problem. Compilation instead throws for invalid options; a successful compiled formatter already has a validated .resolution.
Built-in numeric specifications are checked at runtime as well as by TypeScript. Unknown or wrong-domain keys, invalid wrapper options, and incorrect value types are rejected rather than ignored or coerced. Optional fields may be undefined; an unknown key is still rejected even when its value is undefined.
import { formatter } from "@neutrium/formatter";
formatter.supports({ kind: "number", maximumFractonDigits: 2 }); // false: misspelled key
formatter.supports({ kind: "bytes", base: 1000 }); // false: use byteBase
formatter.supports({ kind: "bytes", byteBase: 999 }); // false: use 1000 or 1024
formatter.supports({ kind: "bytes", byteBase: 1000 }); // true
Support checks do not render or validate a domain value. A supported specification can still reject an invalid value when you call format or parse. Compile valid specifications to reuse their prepared options; ordinary calls observe later edits to caller-owned specifications.
Use resolve() to explain an unavailable presentation without catching an exception. Direct operations and compilation throw the original error. For user-entered text, catch parsing failures at the input boundary and show an application-appropriate validation message; see the parsing guide.
| Error | Meaning | Next step |
|---|---|---|
UnknownFormatError |
The selected registry has no codec for the requested kind |
Use a factory with built-ins, or register the required codec |
DuplicateFormatError |
A codec kind is registered twice | Use a new kind, or construct an isolated registry with exactly the desired codecs |
UnsupportedParseError |
The chosen presentation cannot be parsed | Use a parseable presentation, such as an elapsed duration |
UnsupportedRangeError |
The selected format has no range operation | Check resolution.capabilities.range before offering a range |
UnsupportedOrdinalLocaleError |
No ordinal patterns are available for the language | Supply ordinalPatterns or choose ordinalFallback: "number" |
TypeError or RangeError |
Invalid input/options or a missing runtime feature | Inspect the message, validate inputs, and check the specification with resolve() |
The named errors are available from the root entry. The /parse entry also exports UnknownFormatError, DuplicateFormatError, and UnsupportedParseError. UnsupportedOrdinalLocaleError extends RangeError; the other named errors extend Error. Custom codecs may throw their own errors.
import { formatter } from "@neutrium/formatter";
const result = formatter.resolve({ kind: "bytes", byteBase: 999 });
if (!result.supported)
{
console.error(`${result.error.name}: ${result.error.message}`); // use byteBase 1000 or 1024
}
runtimeCapabilities() from @neutrium/formatter/diagnostics returns one immutable, cached snapshot of the Intl features relevant to the package. It detects behavior rather than relying on browser or Node.js version strings:
import { runtimeCapabilities } from "@neutrium/formatter/diagnostics";
const runtime = runtimeCapabilities();
console.log(JSON.stringify({ intl: runtime }, null, 2));
// Attach this feature report to a support request when output differs between environments.
Use this report to diagnose differences between environments. For example, exactDecimalStrings: false explains why numeric formatting is unavailable, while durationFormat: false affects localized durations. To decide whether a specific presentation will work, use supports(spec) or resolve(spec); a broad feature flag does not validate all its options or locale data.
NodeNext or Bundler module resolution to resolve the package's ESM exports.Intl.NumberFormat.format and formatToParts. Check your target browsers with runtimeCapabilities() and the specifications you use with supports(); support for Intl alone is not sufficient.The package is tested on Node 24 and 26 and on Playwright's Chromium, Firefox, and WebKit builds. Those checks do not guarantee support for older browser releases or every locale. See the development guide for the test matrix.
Install any Intl polyfills before importing this package or querying capabilities; runtime capability results are cached.
Localized durations require native or polyfilled Intl.DurationFormat; there is no automatic fallback. Without it, supports(spec) returns false, resolve(spec) reports the missing service, and localized formatting and compilation throw RangeError. Choose elapsed duration formatting explicitly when you need a fallback, as shown above. Number ranges retain their wrapper fallback. Use resolve(spec) to check requested rounding and presentation options.
Localized punctuation, spacing, and duration wording follow the runtime's locale data. If your application renders on both server and client, check the output on both environments rather than assuming identical strings.