Internationalize JS apps with APIs to format dates, numbers, and strings, including pluralization and handling translations.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Number formatting with support for currencies, units, compact notation, and custom number systems. Provides both individual functions and intl instance methods for locale-aware number presentation with extensive customization options.
Formats numbers according to locale with support for various styles and options.
/**
* Format numbers according to locale and style options
* @param config - Configuration with locale, formats, and error handler
* @param getNumberFormat - Number formatter factory function
* @param value - Number or bigint value to format
* @param options - Formatting options including style, currency, and precision
* @returns Formatted number string
*/
function formatNumber(
config: {
locale: string;
formats: CustomFormats;
onError: OnErrorFn;
},
getNumberFormat: Formatters['getNumberFormat'],
value: number | bigint,
options?: FormatNumberOptions
): string;Formats numbers returning arrays of parts for custom rendering and styling.
/**
* Format numbers returning array of parts for custom rendering
* @param config - Configuration with locale, formats, and error handler
* @param getNumberFormat - Number formatter factory function
* @param value - Number or bigint value to format
* @param options - Formatting options
* @returns Array of number parts with types and values
*/
function formatNumberToParts(
config: {
locale: string;
formats: CustomFormats;
onError: OnErrorFn;
},
getNumberFormat: Formatters['getNumberFormat'],
value: number | bigint,
options?: FormatNumberOptions
): Intl.NumberFormatPart[];Usage Examples:
import { formatNumber, formatNumberToParts, createFormatters } from "@formatjs/intl";
const config = {
locale: 'en-US',
formats: {
number: {
currency: { style: 'currency', currency: 'USD' },
percentage: { style: 'percent', minimumFractionDigits: 1 },
compact: { notation: 'compact', compactDisplay: 'short' }
}
},
onError: console.error
};
const formatters = createFormatters();
// Basic number formatting
const basic = formatNumber(config, formatters.getNumberFormat, 1234.56);
// Result: "1,234.56"
// Currency formatting
const currency = formatNumber(config, formatters.getNumberFormat, 1234.56, {
style: 'currency',
currency: 'USD'
});
// Result: "$1,234.56"
// Percentage formatting
const percentage = formatNumber(config, formatters.getNumberFormat, 0.1234, {
style: 'percent',
minimumFractionDigits: 1
});
// Result: "12.3%"
// Compact notation
const compact = formatNumber(config, formatters.getNumberFormat, 1234567, {
notation: 'compact',
compactDisplay: 'short'
});
// Result: "1.2M"
// Using custom formats
const customCurrency = formatNumber(config, formatters.getNumberFormat, 99.99, {
format: 'currency'
});
// Result: "$99.99"Comprehensive options for number formatting with all Intl.NumberFormat capabilities.
type FormatNumberOptions = Omit<NumberFormatOptions, 'localeMatcher'> & {
/** Named format reference from custom formats */
format?: string;
};
interface NumberFormatOptions {
/** Number formatting style */
style?: 'decimal' | 'currency' | 'percent' | 'unit';
/** Currency code for currency style */
currency?: string;
/** Unit identifier for unit style */
unit?: string;
/** Unit display format */
unitDisplay?: 'short' | 'narrow' | 'long';
/** Whether to use grouping separators */
useGrouping?: boolean | 'always' | 'auto' | 'min2';
/** Minimum number of integer digits */
minimumIntegerDigits?: number;
/** Minimum number of fraction digits */
minimumFractionDigits?: number;
/** Maximum number of fraction digits */
maximumFractionDigits?: number;
/** Minimum number of significant digits */
minimumSignificantDigits?: number;
/** Maximum number of significant digits */
maximumSignificantDigits?: number;
/** Compact display mode */
compactDisplay?: 'short' | 'long';
/** Currency display format */
currencyDisplay?: 'symbol' | 'narrowSymbol' | 'code' | 'name';
/** Currency sign display */
currencySign?: 'standard' | 'accounting';
/** Number notation style */
notation?: 'standard' | 'scientific' | 'engineering' | 'compact';
/** Sign display mode */
signDisplay?: 'auto' | 'never' | 'always' | 'exceptZero';
/** Numbering system */
numberingSystem?: string;
/** Trailing zero display (ES2023) */
trailingZeroDisplay?: 'auto' | 'stripIfInteger';
/** Rounding priority (ES2023) */
roundingPriority?: 'auto' | 'morePrecision' | 'lessPrecision';
/** Rounding increment (ES2023) */
roundingIncrement?: 1 | 2 | 5 | 10 | 20 | 25 | 50 | 100 | 200 | 250 | 500 | 1000 | 2000 | 2500 | 5000;
/** Rounding mode (ES2023) */
roundingMode?: 'ceil' | 'floor' | 'expand' | 'trunc' | 'halfCeil' | 'halfFloor' | 'halfExpand' | 'halfTrunc' | 'halfEven';
}Usage Examples:
// Currency formatting with different display options
const currencySymbol = formatNumber(config, formatters.getNumberFormat, 1234.56, {
style: 'currency',
currency: 'EUR',
currencyDisplay: 'symbol'
});
// Result: "€1,234.56"
const currencyCode = formatNumber(config, formatters.getNumberFormat, 1234.56, {
style: 'currency',
currency: 'EUR',
currencyDisplay: 'code'
});
// Result: "EUR 1,234.56"
const currencyName = formatNumber(config, formatters.getNumberFormat, 1234.56, {
style: 'currency',
currency: 'EUR',
currencyDisplay: 'name'
});
// Result: "1,234.56 euros"
// Unit formatting
const distance = formatNumber(config, formatters.getNumberFormat, 15.5, {
style: 'unit',
unit: 'kilometer',
unitDisplay: 'long'
});
// Result: "15.5 kilometers"
const speed = formatNumber(config, formatters.getNumberFormat, 60, {
style: 'unit',
unit: 'mile-per-hour',
unitDisplay: 'short'
});
// Result: "60 mph"
// Scientific notation
const scientific = formatNumber(config, formatters.getNumberFormat, 123456789, {
notation: 'scientific',
minimumFractionDigits: 2
});
// Result: "1.23E8"
// Engineering notation
const engineering = formatNumber(config, formatters.getNumberFormat, 123456789, {
notation: 'engineering',
minimumFractionDigits: 1
});
// Result: "123.5E6"Use formatNumberToParts for custom styling and rendering.
Usage Examples:
// Currency parts
const currencyParts = formatNumberToParts(config, formatters.getNumberFormat, 1234.56, {
style: 'currency',
currency: 'USD'
});
// Result: [
// { type: 'currency', value: '$' },
// { type: 'integer', value: '1' },
// { type: 'group', value: ',' },
// { type: 'integer', value: '234' },
// { type: 'decimal', value: '.' },
// { type: 'fraction', value: '56' }
// ]
// Custom rendering with parts
const customCurrencyRender = currencyParts
.map(part => {
if (part.type === 'currency') {
return `<span class="currency-symbol">${part.value}</span>`;
}
if (part.type === 'integer') {
return `<span class="integer">${part.value}</span>`;
}
return part.value;
})
.join('');
// Percentage parts with custom styling
const percentParts = formatNumberToParts(config, formatters.getNumberFormat, 0.1234, {
style: 'percent',
minimumFractionDigits: 1
});
// Result: [
// { type: 'integer', value: '12' },
// { type: 'decimal', value: '.' },
// { type: 'fraction', value: '3' },
// { type: 'percentSign', value: '%' }
// ]
// Compact notation parts
const compactParts = formatNumberToParts(config, formatters.getNumberFormat, 1234567, {
notation: 'compact'
});
// Result: [
// { type: 'integer', value: '1' },
// { type: 'decimal', value: '.' },
// { type: 'fraction', value: '2' },
// { type: 'compact', value: 'M' }
// ]Precision control, rounding, and locale-specific options.
Usage Examples:
// Significant digits
const significant = formatNumber(config, formatters.getNumberFormat, 123456.789, {
minimumSignificantDigits: 3,
maximumSignificantDigits: 5
});
// Result: "123,460" (rounded to 5 significant digits)
// Fraction digit control
const fractions = formatNumber(config, formatters.getNumberFormat, 123.456, {
minimumFractionDigits: 2,
maximumFractionDigits: 4
});
// Result: "123.456"
// Accounting currency style
const accounting = formatNumber(config, formatters.getNumberFormat, -1234.56, {
style: 'currency',
currency: 'USD',
currencySign: 'accounting'
});
// Result: "($1,234.56)"
// Always show sign
const alwaysSign = formatNumber(config, formatters.getNumberFormat, 1234, {
signDisplay: 'always'
});
// Result: "+1,234"
// Custom numbering system
const arabicNumbers = formatNumber(
{ ...config, locale: 'ar-EG' },
formatters.getNumberFormat,
1234.56,
{
numberingSystem: 'arab'
}
);
// Result: "١٬٢٣٤٫٥٦"
// Rounding increment (ES2023)
const rounded = formatNumber(config, formatters.getNumberFormat, 1234.567, {
roundingIncrement: 5,
minimumFractionDigits: 2
});
// Result: "1,234.55" (rounded to nearest 0.05)
// No grouping
const noGrouping = formatNumber(config, formatters.getNumberFormat, 1234567, {
useGrouping: false
});
// Result: "1234567"Define reusable number format configurations.
Usage Examples:
const intl = createIntl({
locale: 'en-US',
formats: {
number: {
currency: {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 2,
maximumFractionDigits: 2
},
percentage: {
style: 'percent',
minimumFractionDigits: 1,
maximumFractionDigits: 2
},
compact: {
notation: 'compact',
compactDisplay: 'short',
maximumFractionDigits: 1
},
scientific: {
notation: 'scientific',
minimumFractionDigits: 2,
maximumFractionDigits: 3
},
accounting: {
style: 'currency',
currency: 'USD',
currencySign: 'accounting'
}
}
}
});
// Use custom formats
const price = intl.formatNumber(29.99, { format: 'currency' });
// Result: "$29.99"
const growth = intl.formatNumber(0.1567, { format: 'percentage' });
// Result: "15.7%"
const users = intl.formatNumber(1234567, { format: 'compact' });
// Result: "1.2M"
const measurement = intl.formatNumber(0.00012345, { format: 'scientific' });
// Result: "1.235E-4"
const deficit = intl.formatNumber(-1500, { format: 'accounting' });
// Result: "($1,500.00)"Different locales have different number formatting conventions.
Usage Examples:
const value = 1234567.89;
// German locale (period for thousands, comma for decimal)
const german = formatNumber(
{ ...config, locale: 'de-DE' },
formatters.getNumberFormat,
value
);
// Result: "1.234.567,89"
// French locale (space for thousands, comma for decimal)
const french = formatNumber(
{ ...config, locale: 'fr-FR' },
formatters.getNumberFormat,
value
);
// Result: "1 234 567,89"
// Indian locale (different grouping pattern)
const indian = formatNumber(
{ ...config, locale: 'hi-IN' },
formatters.getNumberFormat,
value
);
// Result: "12,34,567.89"
// Arabic locale with Arabic-Indic digits
const arabic = formatNumber(
{ ...config, locale: 'ar-SA' },
formatters.getNumberFormat,
value,
{ numberingSystem: 'arab' }
);
// Result: "١٬٢٣٤٬٥٦٧٫٨٩"