What does JavaScript's built-in String.raw tag do to a template literal, and what is it used for?
answer
- A tag, not a syntax
- Reads the other view of the text
- Backslashes survive as characters
- Placeholders still interpolate normally
- Windows paths and RegExp sources
basics
~20 sString.raw is a built-in tag function that returns the template's text with backslash escape sequences left uninterpreted, so String.rawa\nb is four characters, not three. It exists for text where a backslash means a backslash: Windows paths, regex sources, and generated code.
solid answer
~40 s`String.raw` is the standard library's tag function that builds the result from the template object's `raw` chunks instead of the cooked ones. Because `raw` holds the characters exactly as typed, escape sequences survive as literal text: `` String.raw`a\nb` `` is the four characters `a`, `\`, `n`, `b`, while the untagged `` `a\nb` `` is three characters containing a real newline. Interpolation still happens normally — `${}` placeholders are evaluated and inserted — so only backslash handling changes. The practical uses are text where a backslash is data: Windows-style paths, regular-expression source strings you plan to pass to `new RegExp`, LaTeX or code generation. It is also the natural way to *see* what `raw` means when explaining tagged templates, since it is nothing more than a tag that joins `strings.raw` with the values.
code
javascript · 8 linesconst dir = 'Users';
console.log(`C:\temp\new`.length); // escapes consumed
console.log(String.raw`C:\temp\new`); // C:\temp\new
console.log(String.raw`C:\${dir}\new`); // C:\Users\new
const pattern = new RegExp(String.raw`\d+\.\d+`);
console.log(pattern.test('3.14')); // truego deeper
Know that String.raw is used in front of a backtick string and keeps backslashes literal, so String.rawa\nb has four characters rather than a real newline.
Explain it as a tag that reads strings.raw instead of the cooked chunks, and name the real uses: Windows paths and regex sources passed to new RegExp.
Judge when raw text is the right tool versus a proper builder — dynamically assembled patterns still need input escaping, and raw only removes one layer of confusion, not injection risk.
Decide whether raw-text DSLs belong in the codebase at all: they read well but defeat some tooling and linting, so set the convention rather than leaving it per-author.
## What it is `String.raw` is a static method on the `String` constructor, added in ES2015, designed to be used as a template tag. Called that way it receives the template object and the interpolated values like any tag, and it concatenates `strings.raw[i]` with `String(values[i])` in order. ```js `a\nb`.length; // 3 -> 'a', newline, 'b' String.raw`a\nb`.length; // 4 -> 'a', '\\', 'n', 'b' ``` Everything else about the literal is unchanged. Placeholders still evaluate eagerly and still splice in: ```js const dir = 'Users'; String.raw`C:\${dir}\new`; // 'C:\\Users\\new' ``` Note what happened there: the `\n` in `\new` did not become a newline, which is exactly the bug `String.raw` exists to prevent. ## Cooked versus raw Every tag function gets both views of the static text. `strings[i]` is **cooked**: `\n` has already become a newline, `\u0041` has already become `A`, `\\` has already become one backslash. `strings.raw[i]` is the source characters. `String.raw` is the trivial tag that picks the second view: ```js function rawish(strings, ...values) { return strings.raw.reduce( (out, chunk, i) => out + chunk + (i < values.length ? String(values[i]) : ''), '' ); } ``` That is essentially the built-in, which is why understanding one explains the other. ## Where it earns its place - **Filesystem paths on Windows.** `'C:\temp\new'` in an ordinary literal silently contains a tab and a newline. `` String.raw`C:\temp\new` `` is the path you meant. - **Regex sources.** Passing a pattern to `new RegExp` normally means doubling every backslash, because the string literal eats one layer: `new RegExp('\\d+')`. With `` new RegExp(String.raw`\d+`) `` the pattern reads as it would in a regex literal, which matters when the pattern is assembled dynamically. - **Code and markup generation, LaTeX, and DSL fragments** where backslash is a meaningful character. It is *not* a general "turn off escaping" switch: the one thing it cannot express is an unescaped backtick or a literal `${`, since those still terminate the literal or start a placeholder and must be escaped with a backslash — which then survives into the output, because raw text keeps it. ## The escape-sequence relaxation An invalid escape sequence such as `\unicorn` is a `SyntaxError` in an ordinary template literal. Since ES2018, in a **tagged** template it is allowed: the cooked entry for that chunk becomes `undefined` while `raw` still contains the text. That is what lets tags host syntaxes with their own backslash rules. `String.raw` never touches the cooked array, so it works fine on such templates; a tag that reads `strings[i]` must be prepared for `undefined`. ```js function t(s) { return [s[0], s.raw[0]]; } t`\unicorn`; // [undefined, '\\unicorn'] ``` ## Calling it as a plain function `String.raw` is an ordinary function, so it can be called directly with an object that has a `raw` property: `String.raw({ raw: ['a', 'b'] }, 1)` returns `'a1b'`. That is a curiosity rather than a technique, but it shows there is no magic in the tag — the tag protocol is just a calling convention.
- Does String.raw stop ${} interpolation as well as escape processing?No. Placeholders behave exactly as in any template: they are evaluated eagerly, converted to strings, and inserted between the raw chunks. Only the treatment of backslash sequences in the static text changes. If you need a literal `${` in the output you must still write `\${`, and the backslash then survives into the result because raw text preserves it.
- How would you write String.raw yourself?Join `strings.raw` with the values: reduce over `strings.raw`, appending each chunk and then `String(values[i])` while `i < values.length`. That is the whole implementation — it demonstrates that `raw` is just the second view of the static text that every tag already receives.
saying these in an interview costs you the question
- Thinks String.raw disables ${} interpolation too
- Calls it syntax rather than an ordinary tag function
- Believes it can emit an unescaped backtick
- Confuses it with escaping output for HTML safety