1# Internationalization support 2 3<!--introduced_in=v8.2.0--> 4<!-- type=misc --> 5 6Node.js has many features that make it easier to write internationalized 7programs. Some of them are: 8 9* Locale-sensitive or Unicode-aware functions in the [ECMAScript Language 10 Specification][ECMA-262]: 11 * [`String.prototype.normalize()`][] 12 * [`String.prototype.toLowerCase()`][] 13 * [`String.prototype.toUpperCase()`][] 14* All functionality described in the [ECMAScript Internationalization API 15 Specification][ECMA-402] (aka ECMA-402): 16 * [`Intl`][] object 17 * Locale-sensitive methods like [`String.prototype.localeCompare()`][] and 18 [`Date.prototype.toLocaleString()`][] 19* The [WHATWG URL parser][]'s [internationalized domain names][] (IDNs) support 20* [`require('buffer').transcode()`][] 21* More accurate [REPL][] line editing 22* [`require('util').TextDecoder`][] 23* [`RegExp` Unicode Property Escapes][] 24 25Node.js (and its underlying V8 engine) uses [ICU][] to implement these features 26in native C/C++ code. However, some of them require a very large ICU data file 27in order to support all locales of the world. Because it is expected that most 28Node.js users will make use of only a small portion of ICU functionality, only 29a subset of the full ICU data set is provided by Node.js by default. Several 30options are provided for customizing and expanding the ICU data set either when 31building or running Node.js. 32 33## Options for building Node.js 34 35To control how ICU is used in Node.js, four `configure` options are available 36during compilation. Additional details on how to compile Node.js are documented 37in [BUILDING.md][]. 38 39* `--with-intl=none`/`--without-intl` 40* `--with-intl=system-icu` 41* `--with-intl=small-icu` (default) 42* `--with-intl=full-icu` 43 44An overview of available Node.js and JavaScript features for each `configure` 45option: 46 47| | `none` | `system-icu` | `small-icu` | `full-icu` | 48|-----------------------------------------|-----------------------------------|------------------------------|------------------------|------------| 49| [`String.prototype.normalize()`][] | none (function is no-op) | full | full | full | 50| `String.prototype.to*Case()` | full | full | full | full | 51| [`Intl`][] | none (object does not exist) | partial/full (depends on OS) | partial (English-only) | full | 52| [`String.prototype.localeCompare()`][] | partial (not locale-aware) | full | full | full | 53| `String.prototype.toLocale*Case()` | partial (not locale-aware) | full | full | full | 54| [`Number.prototype.toLocaleString()`][] | partial (not locale-aware) | partial/full (depends on OS) | partial (English-only) | full | 55| `Date.prototype.toLocale*String()` | partial (not locale-aware) | partial/full (depends on OS) | partial (English-only) | full | 56| [WHATWG URL Parser][] | partial (no IDN support) | full | full | full | 57| [`require('buffer').transcode()`][] | none (function does not exist) | full | full | full | 58| [REPL][] | partial (inaccurate line editing) | full | full | full | 59| [`require('util').TextDecoder`][] | partial (basic encodings support) | partial/full (depends on OS) | partial (Unicode-only) | full | 60| [`RegExp` Unicode Property Escapes][] | none (invalid `RegExp` error) | full | full | full | 61 62The "(not locale-aware)" designation denotes that the function carries out its 63operation just like the non-`Locale` version of the function, if one 64exists. For example, under `none` mode, `Date.prototype.toLocaleString()`'s 65operation is identical to that of `Date.prototype.toString()`. 66 67### Disable all internationalization features (`none`) 68 69If this option is chosen, most internationalization features mentioned above 70will be **unavailable** in the resulting `node` binary. 71 72### Build with a pre-installed ICU (`system-icu`) 73 74Node.js can link against an ICU build already installed on the system. In fact, 75most Linux distributions already come with ICU installed, and this option would 76make it possible to reuse the same set of data used by other components in the 77OS. 78 79Functionalities that only require the ICU library itself, such as 80[`String.prototype.normalize()`][] and the [WHATWG URL parser][], are fully 81supported under `system-icu`. Features that require ICU locale data in 82addition, such as [`Intl.DateTimeFormat`][] *may* be fully or partially 83supported, depending on the completeness of the ICU data installed on the 84system. 85 86### Embed a limited set of ICU data (`small-icu`) 87 88This option makes the resulting binary link against the ICU library statically, 89and includes a subset of ICU data (typically only the English locale) within 90the `node` executable. 91 92Functionalities that only require the ICU library itself, such as 93[`String.prototype.normalize()`][] and the [WHATWG URL parser][], are fully 94supported under `small-icu`. Features that require ICU locale data in addition, 95such as [`Intl.DateTimeFormat`][], generally only work with the English locale: 96 97```js 98const january = new Date(9e8); 99const english = new Intl.DateTimeFormat('en', { month: 'long' }); 100const spanish = new Intl.DateTimeFormat('es', { month: 'long' }); 101 102console.log(english.format(january)); 103// Prints "January" 104console.log(spanish.format(january)); 105// Prints "M01" on small-icu 106// Should print "enero" 107``` 108 109This mode provides a good balance between features and binary size, and it is 110the default behavior if no `--with-intl` flag is passed. The official binaries 111are also built in this mode. 112 113#### Providing ICU data at runtime 114 115If the `small-icu` option is used, one can still provide additional locale data 116at runtime so that the JS methods would work for all ICU locales. Assuming the 117data file is stored at `/some/directory`, it can be made available to ICU 118through either: 119 120* The [`NODE_ICU_DATA`][] environment variable: 121 122 ```bash 123 env NODE_ICU_DATA=/some/directory node 124 ``` 125 126* The [`--icu-data-dir`][] CLI parameter: 127 128 ```bash 129 node --icu-data-dir=/some/directory 130 ``` 131 132(If both are specified, the `--icu-data-dir` CLI parameter takes precedence.) 133 134ICU is able to automatically find and load a variety of data formats, but the 135data must be appropriate for the ICU version, and the file correctly named. 136The most common name for the data file is `icudt6X[bl].dat`, where `6X` denotes 137the intended ICU version, and `b` or `l` indicates the system's endianness. 138Check ["ICU Data"][] article in the ICU User Guide for other supported formats 139and more details on ICU data in general. 140 141The [full-icu][] npm module can greatly simplify ICU data installation by 142detecting the ICU version of the running `node` executable and downloading the 143appropriate data file. After installing the module through `npm i full-icu`, 144the data file will be available at `./node_modules/full-icu`. This path can be 145then passed either to `NODE_ICU_DATA` or `--icu-data-dir` as shown above to 146enable full `Intl` support. 147 148### Embed the entire ICU (`full-icu`) 149 150This option makes the resulting binary link against ICU statically and include 151a full set of ICU data. A binary created this way has no further external 152dependencies and supports all locales, but might be rather large. See 153[BUILDING.md][BUILDING.md#full-icu] on how to compile a binary using this mode. 154 155## Detecting internationalization support 156 157To verify that ICU is enabled at all (`system-icu`, `small-icu`, or 158`full-icu`), simply checking the existence of `Intl` should suffice: 159 160```js 161const hasICU = typeof Intl === 'object'; 162``` 163 164Alternatively, checking for `process.versions.icu`, a property defined only 165when ICU is enabled, works too: 166 167```js 168const hasICU = typeof process.versions.icu === 'string'; 169``` 170 171To check for support for a non-English locale (i.e. `full-icu` or 172`system-icu`), [`Intl.DateTimeFormat`][] can be a good distinguishing factor: 173 174```js 175const hasFullICU = (() => { 176 try { 177 const january = new Date(9e8); 178 const spanish = new Intl.DateTimeFormat('es', { month: 'long' }); 179 return spanish.format(january) === 'enero'; 180 } catch (err) { 181 return false; 182 } 183})(); 184``` 185 186For more verbose tests for `Intl` support, the following resources may be found 187to be helpful: 188 189* [btest402][]: Generally used to check whether Node.js with `Intl` support is 190 built correctly. 191* [Test262][]: ECMAScript's official conformance test suite includes a section 192 dedicated to ECMA-402. 193 194["ICU Data"]: http://userguide.icu-project.org/icudata 195[`--icu-data-dir`]: cli.html#cli_icu_data_dir_file 196[`Date.prototype.toLocaleString()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString 197[`Intl.DateTimeFormat`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat 198[`Intl`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl 199[`NODE_ICU_DATA`]: cli.html#cli_node_icu_data_file 200[`Number.prototype.toLocaleString()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString 201[`RegExp` Unicode Property Escapes]: https://github.com/tc39/proposal-regexp-unicode-property-escapes 202[`String.prototype.localeCompare()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare 203[`String.prototype.normalize()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize 204[`String.prototype.toLowerCase()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase 205[`String.prototype.toUpperCase()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase 206[`require('buffer').transcode()`]: buffer.html#buffer_buffer_transcode_source_fromenc_toenc 207[`require('util').TextDecoder`]: util.html#util_class_util_textdecoder 208[BUILDING.md#full-icu]: https://github.com/nodejs/node/blob/master/BUILDING.md#build-with-full-icu-support-all-locales-supported-by-icu 209[BUILDING.md]: https://github.com/nodejs/node/blob/master/BUILDING.md 210[ECMA-262]: https://tc39.github.io/ecma262/ 211[ECMA-402]: https://tc39.github.io/ecma402/ 212[ICU]: http://site.icu-project.org/ 213[REPL]: repl.html#repl_repl 214[Test262]: https://github.com/tc39/test262/tree/master/test/intl402 215[WHATWG URL parser]: url.html#url_the_whatwg_url_api 216[btest402]: https://github.com/srl295/btest402 217[full-icu]: https://www.npmjs.com/package/full-icu 218[internationalized domain names]: https://en.wikipedia.org/wiki/Internationalized_domain_name 219