// From any currency, to any currency:
fx.convert(12.99, {from: "GBP", to: "HKD"});

// Chaining sugar:
fx(1000).from("USD").to("GBP");
fx(1000).to("AED");

// With simple settings and defaults, making this possible:
fx.convert(5318008);
fx(5318008).to("AED");

// Can also be used as a nodeJS/npm or requireJS/AMD module
var fx = require("money");
require(["money"], function(fx) { /* ... */ });

// Read more below or jump to the downloads, demo playground or documentation
// by @josscrowcroft

 

JavaScript Currency Conversion should be easy!

Forget trying to adapt those 10-year-old "FREE Currency Converter JavaScripts!" into something workable for your enterprise software or shopping cart: money.js is a simple library with one function: to convert a value from any currency to any other currency.

Read on for some background information (recommended!) or jump straight to the downloads, demo playground or documentation.

Introduction

First things first: in order to do currency conversion in JavaScript, you need a reliable source of real-time exchange rates. The industry-standard exchange rate APIs, which people use to make currency trades, may cost anywhere between $100 and $1,000 per month for access!

The fact is though, 99% of apps and shopping carts don't need this expensive level of accuracy!

With that in mind, the Open Exchange Rates API uses algorithmic blending to calculate a consistently accurate and unbiased set of rates for 160 world currencies - and costs 10-20x less than the most popular competitor (with a Forever Free plan for most users).

Also, money.js allows you to use any source of exchange rates.

In the documentation, there are examples showing how to integrate the API data (or any exchange-rate data) with the library, in only a few lines of code.

You only need the conversion rates relative to any single currency, in order to be able to convert values between any other two currencies; money.js does it all for you.

Downloads

NB: these links always point to the latest stable version of money.js:

»  money.js development version (4.3 kb)

»  money.min.js production/minified version (1.1 kb)

There are more download options available on the GitHub repository, at josscrowcroft/money.js.

Demo Playground

Oh hey! You can use this JavaScript Sandbox to play around with money.js and kick the tires a bit. It's running in a separate (sandboxed) scope, but you have access to jQuery ($), underscore (_), accounting.js (accounting) and money.js (fx).

You can use :load script.js to load extra libraries, or try :help if stuck.

Exchange rates should be set up already (defaults = from: "USD", to: "GBP") but if not, try refreshing the page. There are some sample commands to try out below!

sandbox console loading...
Some sample commands to get you started:

Interested in putting the sandbox on your JavaScript library homepage? It's on GitHub at josscrowcroft/javascript-sandbox-console!

Documentation

Basic Installation

You've probably figured this one out, but here's how to use money.js as a standalone library (for modules and script loaders, there are guides lower down.) Just download the minified or development version of money.js, and include it like this:

<script src="path/to/money.js"></script>

You'll need to do one more thing before you can use it, though, which is...

Setting up exchange rates with fx.rates

First and foremost, to convert currencies, you're going to need some exchange rates, and a base currency. (As long as you have exchange rates for every currency relative to one single other ('base') currency, money.js can convert between any two, without going via the base. See fx.convert for details on that.)

The library doesn't really care which format you use for the currency names (but standard three-letter codes are recommended), nor how accurate they are or which currency is your base rate - all that matters is the object format, shown below.

Rates are stored in the fx.rates object, while the base currency is stored in fx.base. They look kinda like this:

fx.base = "USD";
fx.rates = {
	"EUR" : 0.745101, // eg. 1 USD === 0.745101 EUR
	"GBP" : 0.647710, // etc...
	"HKD" : 7.781919,
	"USD" : 1,        // always include the base rate (1:1)
	/* etc */
}

You can include as many or as few currencies as you need, and the rates can be approximate, historical or just plain wrong (though I wouldn't recommend it!)

NB: you need to include the base rate (the currency code from fx.base) in fx.rates object as well, for example "USD" : 1, so that money.js can use it for its calculations.

But wait! Where do these exchange rates come from?

You can use the latest rates from the Open Exchange Rates API, which are delivered in JSON format, ready for use with money.js. You'll need to sign up for an App ID, and you can choose whichever option you need (there is a generous Forever Free plan.)

You could cache the rates on your server, then bootstrap them inline into the HTML - but you can also easily load them in via AJAX, or a script loader. With jQuery, you could do this:

<script type="text/javascript">
    // Load exchange rates data via AJAX:
    $.getJSON(
    	// NB: using Open Exchange Rates here, but you can use any source!
        'http://openexchangerates.org/api/latest.json?app_id=[YOUR APP ID]',
        function(data) {
            // Check money.js has finished loading:
            if ( typeof fx !== "undefined" && fx.rates ) {
                fx.rates = data.rates;
                fx.base = data.base;
            } else {
                // If not, apply to fxSetup global:
                var fxSetup = {
                    rates : data.rates,
                    base : data.base
                }
            }
        }
    );
</script>

AJAX works great, but you'll need to wait until the AJAX request has completed before you can get converting. Therefore you should have a plan B, for example, inlining the approximate/cached exchange rates which could be used while the AJAX request is loading.

You could also skip using AJAX and use the slightly more reliable bootstrapping method - which will also require fewer API requests - using CURL or some other library to grab the file, then printing them out in a script tag.

This works in any language or framework, but here's a PHP example:

<?php
	// Bootstrap loaded exchange rates into JavaScript for money.js:
	echo '<script>fx.rates = ' . json_encode($exchangeRates->rates) . '; fx.base = ' . json_encode($exchangeRates->base) . '</script>';
?>

There are more examples and methods of grabbing the latest (and historical) data, for all the most common languages and frameworks, on the Open Exchange Rates site (check out the documentation).

Whichever API or data source you use, all you need to make certain of is that there is a base currency, and that the exchange rates are in the object format given above.

fx.settings and fxSetup

You can use fx.settings to set default from and to currencies, after the library has loaded. If you want or need to set these before the library has loaded, create a global object called fxSetup, with the same properties:

// Using `fx.settings` (must be after loading the library)
fx.settings = {
	from : "GBP",
	to : "AED"
};

// Using `fxSetup` (must be before loading the library; see note)
var fxSetup = {
	from : "GBP",
	to : "AED"
};

Note about using fxSetup: If using fxSetup, the variable needs to be available to the library (in scope) - so use window.fxSetup if needed. Also note that the fxSetup method won't work if using money.js as an AMD / CommonJS module, because it won't have access to outside variables (so use fx.settings for those).

Oh, and you can also use fxSetup to load in the exchange rates and base currency before loading the library, which would look something like this:

// Adding exchange rates and base currency to `fxSetup`:
var fxSetup = {
	from : "GBP",
	to : "AED",
	base : "USD",
	rates : {
		"AED" : 3.672905
		/* etc. */
	}
};

fx.convert(val, [opts])

The basic function of the library - converts a value from one currency to another. Uses the default from and to currencies in fx.settings, or those given in opts:

// Using defaults:
fx.settings = { from: "USD", to: "GBP" };
fx.convert(1000); // 647.71034

// With options:
fx.convert(1000, {to: "HKD"}); // 7781.91949 (default `from` currency)
fx.convert(1000, {from: "GBP", to: "HKD"}); // 12014.50549

fx.convert can convert from any currency to any currency, provided they're both in the fx.rates object. For example, if all rates are relative to USD (1:1), and you have the rate for USD:GBP and USD:HKD, you can specify {from: "GBP", to: "HKD"} - money.js will figure out the rate between the two currencies.

Currency names

Currency names directly reference entries in the fx.rates object, so you're not limited to using the standard 3-letter currency codes. If for some reason your exchange rates API gives pounds (£) as "British Pounds Sterling", that's what you'd use instead of "GBP". Same goes for other currencies.

If you pass in a currency in from or to for which you don't have an exchange rate, money.js will throw an error to let you know that the rate wasn't found.

Pro Tip disclaimer:

It's a good idea to inform your users that the exchange rates / currency conversion is for informational purposes only. Exchange rates can never be truly accurate and you don't want to be dealing with customers who are angry because their bank charged them $1.40 more than your website quoted!

fx.noConflict() available in standalone mode (not AMD/CJS)

Let's face it, fx is a pretty common namespace (think 'animation'), so money.js stores a reference to the previous global value of fx, if any, in case you need to restore it.

If you're using another library that creates a global fx object or function, you can use fx.noConflict to restore its value and, at the same time, assign the money.js library object to another variable:

// Assign the money.js library to a global money object:
var money = fx.noConflict();

// `fx` is now back to whatever it was before money.js was loaded, and you can still use the library via the `money` reference, like so:
money.convert(5318008);
money.settings.from = "JPY";
money(5318008).to("HKD");

Chaining with fx(val)

money.js provides basic 'chaining' (i.e. connecting method calls together, with each acting on the value returned by the previous.)

This allows a more expressive, human-readable way of writing code, where the underlying functions are exactly the same. The methods are as follows:

fx() returns a wrapped fx object for chaining (doesn't do any converting)
fx(16288) // (fxWrapper)

// NB: if parameter is a string, fx() will attempt to parse it to extract the
// `from` currency and `value`, so this is the same as the next example:
fx("$16288 HKD") // (fxWrapper)
.from() returns a wrapped fx object, with the value converted from base to from currency:
fx(16288).from("HKD") // (fxWrapper)
.to() takes a wrapped fx object and converts to target currency:
fx(16288).to("GBP"); // 10549.906083 (uses default `from` currency)
fx(16288).from("AED").to("GBP"); // 2872.359629
.convert() takes a wrapped fx object and performs fx.convert(val, [opts]) on it:
fx(16288).convert(); // uses default `from` / `to` currencies
fx(16288).convert({ from:"HKD", to:"GBP" }); // 1355.694581

Usage with accounting.js

money.js works great with accounting.js - a library that provides reliable localisation and formatting of money and currency. Here are a few examples, just for kicks:

var value = accounting.unformat(someNumber); // clean up number (eg. user input)
var target = "GBP"; // or some user input
var convertedValue = fx(value).from("USD").to(target);

accounting.formatMoney(convertedValue, {
	symbol: target,
	format: "%v %s"
}); // eg. "53,180.08 GBP"

This works because money.js can give high precision results (eg. 8 decimal places, depending on the rates and input value), which is overkill if you're displaying prices with 0 or 2 decimal places. accounting.js takes care of all the formatting.

You could use the native value.toFixed(2) of course, but we all know how quirky (read: ‘arghh!’) that can be. accounting.toFixed() is a reliable replacement:

// accounting.toFixed() is a replacement for (Number).toFixed():
(0.615).toFixed(2);           // "0.61" <== wtfjs??
accounting.toFixed(0.615, 2); // "0.62" <== better

Usage in nodeJS/npm (CommonJS)

money.js can easily be used inside nodeJS or any other CommonJS module loader:

var fx = require("/path/to/money");
// Now load in your exchange rates and create `fx.settings` if needed

// NB: check out the exchange-rates npm module

You can also install it via npm install money, then just use:

var fx = require("money");

Usage as a RequireJS/AMD module

money.js also exposes itself (ha ha) as an AMD module, for script loaders such as RequireJS. This assumes you've read up on AMD modules and understand the syntax:

// Usage as a dependency:
require(["path/to/money"], function(fx) {
	// Now you have a well-scoped `fx` object to use!
	fx.convert(5318008);
});

You'll need to set up money.js inside the callback function, with fx.rates, fx.base and (optionally) fx.settings - once those are set up, they'll also be set up anywhere else you use fx.

That just about sums it up

That's really all you need to remember - fx.rates and fx.base are important, and your basic function is fx.convert(val, [opts]), which can be written like this: fx(val).from("USD").to("GBP") or in several other ways (re-read the docs if unsure.)

Feedback / bugs:

If you have any feedback, any at all, tweet @josscrowcroft, or head over to the money.js github repository and create a new issue. Pull requests / contributions welcome!