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