currency.js
A small, lightweight javascript library for working with currency values.
Download currency.jsv2.0.3 (1.14 kB)
Installation
With npm:
npm install --save currency.js
With yarn:
yarn add currency.js
Usage
currency.js was built to work around common floating point issues in javascript with a flexible api.
When working with currencies, decimals only need to be precise up to the smallest cent value while avoiding common floating point errors when performing basic arithmetic. currency.js resolves this issue by working with integers behind the scenes, so you don't have to be concerned about decimal precision.
For more details on why Javascript has issues with floating point numbers, there's an excellent talk by Bartek Szopka on everything you never wanted to know about Javascript numbers explaining why Javascript and other IEEE 754 implementations have floating point issues.
currency.js will work with a range of inputs, including strings
, numbers
, decimals
, or another currency
object.
// Numbers
currency(1); // => "1.00"
currency(123); // => "123.00"
// Decimals
currency(1.00); // => "1.00"
currency(1.23); // => "1.23"
// Strings
currency("1.23"); // => "1.23"
currency("$12.30"); // => "12.30"
currency("£1,234,567.89"); // => "1,234,567.89"
// Currency
let c1 = currency(1.23);
let c2 = currency(4.56);
currency(7.89).add(c1).add(c2); // => "13.68"
Currency values are handled transparently behind the scenes, so you don't have to worry about those pesky floating point issues!
2.51 + .01; // => 2.5199999999999996
currency(2.51).add(.01); // => 2.52
2.52 - .01; // 2.5100000000000002
currency(2.52).subtract(.01); // 2.51
Since currency.js handles values internally as integers, there is a limit to the precision that can be stored before encountering precision errors. This should be okay for most reasonable values of currencies. As long as your currencies are less than 253 (in cents) or 90,071,992,547,409.91
, you should not see any problems.
currency.js also works with a variety of strings. This makes it easy to work into your UI without having to do string to number conversion or vice versa.
var c = currency("$1,234.56").add("890.12"); // 2124.68
c.format(); // 2,124.68
// Negative values
currency("-$5,000").add(1234.56); // -3765.44
currency("($5,000)").add(1234.56); // -3765.44
By default, currency resolves to a string
value.
// Sets the first input to the resolved currency value
document.getElementsByTagName("input")[0].value = currency(1234.56).add(6.44); // 1241.00
If you need access to the raw numbers, the value is stored as both an integer
and a string
, which you can access with .intValue
or .value
;
// Get the internal values
currency(123.45).add(.1).value; // => 123.55
currency(123.45).add(.1).intValue; // => 12355
Options
You can customize the formatting and parsing of currency.js
with an optional options object. These values default to US centric currency values, but they can be overridden based on your locale.
symbol default: "$"
currency(1.23).format(); // => "$1.23"
separator default: ","
Separator between the number groupings when calling currency.format()
.
currency(1234.56, { separator: ',' }).format(); // => "1,234.56"
currency(1234.56, { separator: ' ' }).format(); // => "1 234.56"
decimal default: "."
currency(1.23, { decimal: '.' }).format(); // => "$1.23"
currency(1.23, { decimal: ',' }).format(); // => "$1,23"
precision default: 2
Number of decimal places to store as cents.
currency(1.234, { precision: 2 }); // => "1.23"
currency(1.234, { precision: 3 }); // => "1.234"
pattern default: !#
Allows you to customize the format pattern using !
as replacement for the currency symbol and #
as replacement for the currency amount.
currency(1.23, {
pattern: `# !`
}).format(); // => "1.23 $"
negativePattern default: -!#
Allows you to customize the negative format pattern using !
as replacement for the currency symbol and #
as replacement for the currency amount.
currency(-1.23, {
negativePattern: `(!#)`
}).format(); // => "($1.23)"
format default: null
Allows you to customize the format of the currency when calling currency.format()
. format
passes in the currency
object as well as the options
object to the function and expects a string to be returned. Use this when the provided formatting options do not meet your needs.
function format(currency, options) {
return `${currency.dollars()}.${currency.cents()}`;
}
currency(1234.56, { format }).format(); // => "1234.56"
fromCents default: false
Currency accepts decimal values (i.e. 1.23
) with a default precision of 2, but can accept a minor currency unit (e.g. cents in a dollar). This will respect the precision option when parsing.
currency(123456, { fromCents: true }); // => "1234.56"
currency('123456', { fromCents: true }); // => "1234.56"
currency(123456, { fromCents: true, precision: 0 }); // => "123456"
currency(123456, { fromCents: true, precision: 3 }); // => "123.456"
errorOnInvalid default: false
If an invalid value such as null
or undefined
is passed in, currency
will throw an error.
currency(undefined, { errorOnInvalid: true }); // throws an error
increment default: null
When implementing a currency that implements rounding, setting the increment
value will allow you to set the closest increment to round the display value to.
var currencyRounding = value => currency(value, { increment: .05 });
currencyRounding(1.09); // => { intValue: 109, value: 1.09 }
currencyRounding(1.09).format(); // => "1.10"
currencyRounding(1.06); // => { intValue: 106, value: 1.06 }
currencyRounding(1.06).format(); // => "1.05"
useVedic default: false
When using a currency that implements the Indian Numbering System, setting useVedic
will format values with the correct groupings, i.e. 10,00,000.00
.
currency(1234567.89, { useVedic: true }).format(); // => "12,34,567.89"
API
Properties
value
currency.value
Returns the decimal value of the currency.
currency("123.45").add(.01).value; // => 123.46
intValue
currency.intValue
Returns the integer value of the currency.
currency("123.45").add(.01).intValue; // => 12346
Methods
add
currency.add( value )
Adds a string
, number
, or currency
value to the current currency instance.
currency(123.45).add(.01); // => "123.46"
subtract
currency.subtract( value )
Subtracts a string
, number
, or currency
value to the current currency instance.
currency(123.45).subtract(.01); // => "123.44"
multiply
currency.multiply( number )
Multiplies the current currency instance by number
.
currency(123.45).multiply(2); // => "246.90"
divide
currency.divide( number )
Divides the current currency instance by number
.
currency(123.45).divide(2); // => "61.73"
distribute
currency.distribute( number )
Distribute takes the currency value, and tries to distribute the amount evenly. Any extra cents left over from the distribution will be stacked onto the first sets of entries.
currency(12.35).distribute(3); // => [4.12, 4.12, 4.11]
currency(12.00).distribute(3); // => [4.00, 4.00, 4.00]
format
currency.format([ function | options ])
A simple formatter that returns a human friendly currency format.
currency(1000.00).format(); // => "$1,000.00"
currency("1,234,567/90").add("200,000").format(); // => "$1,434,567.89"
The default formatter can be overridden by passing in options as a second parameter.
var euro = value => currency(value, { separator: ' ', decimal: ',', format: ... });
// ...
euro(1000.00).format(); // => "1 000,00"
euro(1234567.89).add("200 000").format(); // => "1 434 567,89"
dollars
currency.dollars
Returns the dollar value of the currency.
currency(123.45).dollars(); // => 123
currency("0.99").dollars(); // => 0
cents
currency.cents
Returns the cent value of the currency.
currency(123.45).cents(); // => 45
currency("0.99").cents(); // => 99
Internationalization (i18n) and Formatting
currency.js defaults to a US locale, but is flexible enough to work with any type of format. Since each currency instance is immutable, you can create multiple instances to work with any number of different international formats.
const USD = value => currency(value);
const JPY = value => currency(value, { precision: 0, symbol: '¥' });
const EURO = value => currency(value, { symbol: '€', decimal: ',', separator: '.' });
USD(1234.567).format(); // => "$1,234.57"
JPY(1234.567).format(); // => "¥1,235"
EURO(1234.567).format(); // => "€1.234,57"
Addons
babel-plugin-transform-currency-operators
An experimental babel plugin for transforming currency operators: currency(1.23) + 4.56
to currency(1.23).add(4.56)
.