currency logo

currency.js

A small, lightweight javascript library for working with currency values.

Download currency.js

v1.2.2 (1.11 kB)

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 252 (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 do 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.46
currency(123.45).add(.1).intValue; // => 12346

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: "$"

When formatWithSymbol is set to true, this currency symbol will be used when calling currency.format().

currency(1.23, { formatWithSymbol: true }).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"

formatWithSymbol default: false

Includes the symbol option when calling currency.format().

currency(1.23, { formatWithSymbol: true }).format(); // => "$1.23"
currency(1.23, { formatWithSymbol: false }).format(); // => "1.23"

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: `# !`,
  formatWithSymbol: true
}).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: `(!#)`,
  formatWithSymbol: true
}).format(); // => "($1.23)"

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([ boolean ])

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: ',' });

// ...

euro(1000.00).format(); // => "1 000,00"
euro(1234567.89).add("200 000").format(); // => "1 434 567,89"

You can also include the currently set symbol option in a couple of different ways. By default it's always turned off, but you can turn it on for all instances of the object via options, or by passing in a boolean operator to the format() function.

var money = value => currency(value, { formatWithSymbol: true });

money(1000.00).format(); // => "$1,000.00"
money(1000.00).format(false); // => "1,000.00"

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(true); // => "$1,234.57"
JPY(1234.567).format(true); // => "¥1,235"
EURO(1234.567).format(true); // => "€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).

Issues/Feedback

Found a problem? Have an idea? File an issue on GitHub.