node package manager

Introducing npm Enterprise add-ons. Integrate third-party dev tools into npm…

jsesc

A JavaScript library for escaping JavaScript strings while generating the shortest possible valid output.

jsesc

This is a JavaScript library for escaping JavaScript strings while generating the shortest possible valid ASCII-only output. Here’s an online demo.

This can be used to avoid mojibake and other encoding issues, or even to avoid errors when passing JSON-formatted data (which may contain U+2028 LINE SEPARATOR, U+2029 PARAGRAPH SEPARATOR, or lone surrogates) to a JavaScript parser or an UTF-8 encoder, respectively.

Feel free to fork if you see possible improvements!

Via npm:

npm install jsesc

In Node.js:

const jsesc = require('jsesc');

This function takes a value and returns an escaped version of the value where any characters that are not printable ASCII symbols are escaped using the shortest possible (but valid) escape sequences for use in JavaScript strings. The first supported value type is strings:

jsesc('Ich ♥ Bücher');
// → 'Ich \\u2665 B\\xFCcher' 
 
jsesc('foo 𝌆 bar');
// → 'foo \\uD834\\uDF06 bar' 

Instead of a string, the value can also be an array, an object, a map, a set, or a buffer. In such cases, jsesc will return a stringified version of the value where any characters that are not printable ASCII symbols are escaped in the same way.

// Escaping an array 
jsesc([
  'Ich ♥ Bücher', 'foo 𝌆 bar'
]);
// → '[\'Ich \\u2665 B\\xFCcher\',\'foo \\uD834\\uDF06 bar\']' 
 
// Escaping an object 
jsesc({
  'Ich ♥ Bücher': 'foo 𝌆 bar'
});
// → '{\'Ich \\u2665 B\\xFCcher\':\'foo \\uD834\\uDF06 bar\'}' 

The optional options argument accepts an object with the following options:

The default value for the quotes option is 'single'. This means that any occurrences of ' in the input string will be escaped as \', so that the output can be used in a string literal wrapped in single quotes.

jsesc('Lorem ipsum "dolor" sit \'amet\' etc.');
// → 'Lorem ipsum "dolor" sit \\\'amet\\\' etc.' 
 
jsesc('Lorem ipsum "dolor" sit \'amet\' etc.', {
  'quotes': 'single'
});
// → 'Lorem ipsum "dolor" sit \\\'amet\\\' etc.' 
// → "Lorem ipsum \"dolor\" sit \\'amet\\' etc." 

If you want to use the output as part of a string literal wrapped in double quotes, set the quotes option to 'double'.

jsesc('Lorem ipsum "dolor" sit \'amet\' etc.', {
  'quotes': 'double'
});
// → 'Lorem ipsum \\"dolor\\" sit \'amet\' etc.' 
// → "Lorem ipsum \\\"dolor\\\" sit 'amet' etc." 

This setting also affects the output for arrays and objects:

jsesc({ 'Ich ♥ Bücher': 'foo 𝌆 bar' }, {
  'quotes': 'double'
});
// → '{"Ich \\u2665 B\\xFCcher":"foo \\uD834\\uDF06 bar"}' 
 
jsesc([ 'Ich ♥ Bücher', 'foo 𝌆 bar' ], {
  'quotes': 'double'
});
// → '["Ich \\u2665 B\\xFCcher","foo \\uD834\\uDF06 bar"]' 

The default value for the numbers option is 'decimal'. This means that any numeric values will be represented using decimal integer literals. Other valid options are binary, octal, and hexadecimal, which result in binary integer literals, octal integer literals, and hexadecimal integer literals, respectively.

jsesc(42, {
  'numbers': 'binary'
});
// → '0b101010' 
 
jsesc(42, {
  'numbers': 'octal'
});
// → '0o52' 
 
jsesc(42, {
  'numbers': 'decimal'
});
// → '42' 
 
jsesc(42, {
  'numbers': 'hexadecimal'
});
// → '0x2A' 

The wrap option takes a boolean value (true or false), and defaults to false (disabled). When enabled, the output will be a valid JavaScript string literal wrapped in quotes. The type of quotes can be specified through the quotes setting.

jsesc('Lorem ipsum "dolor" sit \'amet\' etc.', {
  'quotes': 'single',
  'wrap': true
});
// → '\'Lorem ipsum "dolor" sit \\\'amet\\\' etc.\'' 
// → "\'Lorem ipsum \"dolor\" sit \\\'amet\\\' etc.\'" 
 
jsesc('Lorem ipsum "dolor" sit \'amet\' etc.', {
  'quotes': 'double',
  'wrap': true
});
// → '"Lorem ipsum \\"dolor\\" sit \'amet\' etc."' 
// → "\"Lorem ipsum \\\"dolor\\\" sit \'amet\' etc.\"" 

The es6 option takes a boolean value (true or false), and defaults to false (disabled). When enabled, any astral Unicode symbols in the input will be escaped using ECMAScript 6 Unicode code point escape sequences instead of using separate escape sequences for each surrogate half. If backwards compatibility with ES5 environments is a concern, don’t enable this setting. If the json setting is enabled, the value for the es6 setting is ignored (as if it was false).

// By default, the `es6` option is disabled: 
jsesc('foo 𝌆 bar 💩 baz');
// → 'foo \\uD834\\uDF06 bar \\uD83D\\uDCA9 baz' 
 
// To explicitly disable it: 
jsesc('foo 𝌆 bar 💩 baz', {
  'es6': false
});
// → 'foo \\uD834\\uDF06 bar \\uD83D\\uDCA9 baz' 
 
// To enable it: 
jsesc('foo 𝌆 bar 💩 baz', {
  'es6': true
});
// → 'foo \\u{1D306} bar \\u{1F4A9} baz' 

The escapeEverything option takes a boolean value (true or false), and defaults to false (disabled). When enabled, all the symbols in the output will be escaped, even printable ASCII symbols.

jsesc('lolwat"foo\'bar', {
  'escapeEverything': true
});
// → '\\x6C\\x6F\\x6C\\x77\\x61\\x74\\"\\x66\\x6F\\x6F\\\'\\x62\\x61\\x72' 
// → "\\x6C\\x6F\\x6C\\x77\\x61\\x74\\\"\\x66\\x6F\\x6F\\'\\x62\\x61\\x72" 

This setting also affects the output for arrays and objects:

jsesc({ 'Ich ♥ Bücher': 'foo 𝌆 bar' }, {
  'escapeEverything': true
});
// → '{\'\x49\x63\x68\x20\u2665\x20\x42\xFC\x63\x68\x65\x72\':\'\x66\x6F\x6F\x20\uD834\uDF06\x20\x62\x61\x72\'}' 
// → "{'\x49\x63\x68\x20\u2665\x20\x42\xFC\x63\x68\x65\x72':'\x66\x6F\x6F\x20\uD834\uDF06\x20\x62\x61\x72'}" 
 
jsesc([ 'Ich ♥ Bücher': 'foo 𝌆 bar' ], {
  'escapeEverything': true
});
// → '[\'\x49\x63\x68\x20\u2665\x20\x42\xFC\x63\x68\x65\x72\',\'\x66\x6F\x6F\x20\uD834\uDF06\x20\x62\x61\x72\']' 

The escapeEtago option takes a boolean value (true or false), and defaults to false (disabled). When enabled, occurrences of </script and </style in the output are escaped as <\/script and <\/style. This setting is useful when jsesc’s output ends up as part of a <script> or <style> element in an HTML document.

jsesc('foo</script>bar', {
  'escapeEtago': true
});
// → 'foo<\\/script>bar' 

The compact option takes a boolean value (true or false), and defaults to true (enabled). When enabled, the output for arrays and objects will be as compact as possible; it won’t be formatted nicely.

jsesc({ 'Ich ♥ Bücher': 'foo 𝌆 bar' }, {
  'compact': true // this is the default 
});
// → '{\'Ich \u2665 B\xFCcher\':\'foo \uD834\uDF06 bar\'}' 
 
jsesc({ 'Ich ♥ Bücher': 'foo 𝌆 bar' }, {
  'compact': false
});
// → '{\n\t\'Ich \u2665 B\xFCcher\': \'foo \uD834\uDF06 bar\'\n}' 
 
jsesc([ 'Ich ♥ Bücher', 'foo 𝌆 bar' ], {
  'compact': false
});
// → '[\n\t\'Ich \u2665 B\xFCcher\',\n\t\'foo \uD834\uDF06 bar\'\n]' 

This setting has no effect on the output for strings.

The indent option takes a string value, and defaults to '\t'. When the compact setting is enabled (true), the value of the indent option is used to format the output for arrays and objects.

jsesc({ 'Ich ♥ Bücher': 'foo 𝌆 bar' }, {
  'compact': false,
  'indent': '\t' // this is the default 
});
// → '{\n\t\'Ich \u2665 B\xFCcher\': \'foo \uD834\uDF06 bar\'\n}' 
 
jsesc({ 'Ich ♥ Bücher': 'foo 𝌆 bar' }, {
  'compact': false,
  'indent': '  '
});
// → '{\n  \'Ich \u2665 B\xFCcher\': \'foo \uD834\uDF06 bar\'\n}' 
 
jsesc([ 'Ich ♥ Bücher', 'foo 𝌆 bar' ], {
  'compact': false,
  'indent': '  '
});
// → '[\n  \'Ich \u2665 B\xFCcher\',\n\  t\'foo \uD834\uDF06 bar\'\n]' 

This setting has no effect on the output for strings.

The indentLevel option takes a numeric value, and defaults to 0. It represents the current indentation level, i.e. the number of times the value of the indent option is repeated.

jsesc(['a', 'b', 'c'], {
  'compact': false,
  'indentLevel': 1
});
// → '[\n\t\t\'a\',\n\t\t\'b\',\n\t\t\'c\'\n\t]' 
 
jsesc(['a', 'b', 'c'], {
  'compact': false,
  'indentLevel': 2
});
// → '[\n\t\t\t\'a\',\n\t\t\t\'b\',\n\t\t\t\'c\'\n\t\t]' 

The json option takes a boolean value (true or false), and defaults to false (disabled). When enabled, the output is valid JSON. Hexadecimal character escape sequences and the \v or \0 escape sequences will not be used. Setting json: true implies quotes: 'double', wrap: true, es6: false, although these values can still be overridden if needed — but in such cases, the output won’t be valid JSON anymore.

jsesc('foo\x00bar\xFF\uFFFDbaz', {
  'json': true
});
// → '"foo\\u0000bar\\u00FF\\uFFFDbaz"' 
 
jsesc({ 'foo\x00bar\xFF\uFFFDbaz': 'foo\x00bar\xFF\uFFFDbaz' }, {
  'json': true
});
// → '{"foo\\u0000bar\\u00FF\\uFFFDbaz":"foo\\u0000bar\\u00FF\\uFFFDbaz"}' 
 
jsesc([ 'foo\x00bar\xFF\uFFFDbaz', 'foo\x00bar\xFF\uFFFDbaz' ], {
  'json': true
});
// → '["foo\\u0000bar\\u00FF\\uFFFDbaz","foo\\u0000bar\\u00FF\\uFFFDbaz"]' 
 
// Values that are acceptable in JSON but aren’t strings, arrays, or object 
// literals can’t be escaped, so they’ll just be preserved: 
jsesc([ 'foo\x00bar', [1, '©', { 'foo': true, 'qux': null }], 42 ], {
  'json': true
});
// → '["foo\\u0000bar",[1,"\\u00A9",{"foo":true,"qux":null}],42]' 
// Values that aren’t allowed in JSON are run through `JSON.stringify()`: 
jsesc([ undefined, -Infinity ], {
  'json': true
});
// → '[null,null]' 

Note: Using this option on objects or arrays that contain non-string values relies on JSON.stringify(). For legacy environments like IE ≤ 7, use a JSON polyfill.

The lowercaseHex option takes a boolean value (true or false), and defaults to false (disabled). When enabled, any alphabetical hexadecimal digits in escape sequences as well as any hexadecimal integer literals (see the numbers option) in the output are in lowercase.

jsesc('Ich ♥ Bücher', {
  'lowercaseHex': true
});
// → 'Ich \\u2665 B\\xfccher' 
//                    ^^ 
 
jsesc(42, {
  'numbers': 'hexadecimal',
  'lowercaseHex': true
});
// → '0x2a' 
//      ^^ 

A string representing the semantic version number.

To use the jsesc binary in your shell, simply install jsesc globally using npm:

npm install -g jsesc

After that you will be able to escape strings from the command line:

$ jsesc 'föo ♥ bår 𝌆 baz'
f\xF6o \u2665 b\xE5r \uD834\uDF06 baz

To escape arrays or objects containing string values, use the -o/--object option:

$ jsesc --object '{ "föo": "♥", "bår": "𝌆 baz" }'
{'f\xF6o':'\u2665','b\xE5r':'\uD834\uDF06 baz'}

To prettify the output in such cases, use the -p/--pretty option:

$ jsesc --pretty '{ "föo": "♥", "bår": "𝌆 baz" }'
{
  'f\xF6o': '\u2665',
  'b\xE5r': '\uD834\uDF06 baz'
}

For valid JSON output, use the -j/--json option:

$ jsesc --json --pretty '{ "föo": "♥", "bår": "𝌆 baz" }'
{
  "f\u00F6o": "\u2665",
  "b\u00E5r": "\uD834\uDF06 baz"
}

Read a local JSON file, escape any non-ASCII symbols, and save the result to a new file:

$ jsesc --json --object < data-raw.json > data-escaped.json

Or do the same with an online JSON file:

$ curl -sL "http://git.io/aorKgQ" | jsesc --json --object > data-escaped.json

See jsesc --help for the full list of options.

As of v2.0.0, jsesc supports Node.js v4+ only.

Older versions (up to jsesc v1.3.0) support Chrome 27, Firefox 3, Safari 4, Opera 10, IE 6, Node.js v6.0.0, Narwhal 0.3.2, RingoJS 0.8-0.11, PhantomJS 1.9.0, and Rhino 1.7RC4. Note: Using the json option on objects or arrays that contain non-string values relies on JSON.parse(). For legacy environments like IE ≤ 7, use a JSON polyfill.

Mathias Bynens

This library is available under the MIT license.