JavaScriptTemplate Literals

Template Literals

Template literals — sometimes called template strings — are strings delimited by backticks (`) instead of quotes. They add three features that plain strings lack: interpolation (drop variables and expressions straight into the text), multi-line strings out of the box, and tagged templates for advanced cases like HTML escaping or SQL building. They were added in ES2015 and have quietly replaced almost all old-style string concatenation.

The basics

JS
const name = "Ada";
const age = 36;

// Old way
const a = "Hello, " + name + "! You are " + age + ".";

// Template literal
const b = `Hello, ${name}! You are ${age}.`;

console.log(b);
Hello, Ada! You are 36.

The ${...} is an interpolation placeholder. The expression inside is evaluated, converted to a string, and spliced into the result.

Any expression goes inside \$

JS
const items = ["apple", "pear", "kiwi"];

`We have ${items.length} fruit.`;
`Total: ${1 + 2 + 3}`;
`Name in caps: ${"ada".toUpperCase()}`;
`Mood: ${age > 30 ? "old soul" : "young"}`;

// Nested template literals are fine
const greet = (n) => `Hi, ${n}!`;
`Message: ${greet(name.toUpperCase())}`;

Inside ${...} you can use any JavaScript expression — function calls, conditionals, math, even another template literal. You cannot use statements (if, for, return), but the ternary covers most needs.

Multi-line strings

Plain strings need \ escapes for line breaks. Template literals just keep the newlines you type:

JS
const old = "line 1\nline 2\nline 3";

const modern = `line 1
line 2
line 3`;

console.log(modern);
line 1
line 2
line 3
Indentation is preserved literally
Every space at the start of a line inside the literal ends up in the string. If you don't want them, either keep the literal flush-left or strip a common prefix with a small helper.
Escapes still work

JS
`new\nline`;          // contains a real newline
`tab\there`;          // contains a real tab
`backtick: \`hi\``;     // contains literal backticks
`dollar: \${not a placeholder}`; // contains literal ${ }
`backslash: \\`;

The only two things you ever need to escape inside a template literal are a backtick (\\``) and a dollar sign followed by an open brace (\${`).

Common patterns

JS
// URL building
const id = 42;
const url = `https://api.example.com/users/${id}`;

// Error messages
function load(id) {
  if (typeof id !== "number") {
    throw new TypeError(`Expected a number, got ${typeof id}: ${id}`);
  }
}

// Small templates inside JSX-like code
const html = `<li class="user">${name}</li>`;

// CSS-in-JS
const styles = `
  color: white;
  background: ${theme.primary};
  padding: ${spacing(2)};
`;
Template literals love refactoring
When you find yourself writing a chain of `"foo " + x + " bar " + y + "."`, almost always switch to a template literal. It's shorter, harder to mess up, and clearer to read.
Tagged templates — a preview

A tag is a function placed before a template literal. The runtime calls it with the literal's static parts and its evaluated expressions, giving you full control over how the final string is built.

JS
function tag(strings, ...values) {
  console.log("strings:", strings);
  console.log("values: ", values);
  return strings.raw.join(" / ");
}

const a = 1, b = 2;
tag`sum: ${a} + ${b} = ${a + b}`;
strings: ["sum: ", " + ", " = ", ""]
values:  [1, 2, 3]

That's surprisingly powerful. Real-world uses include:

  • Safe HTMLhtml\

    ${userInput}
    `` where the tag escapes the values to prevent XSS.

  • SQL/GraphQL builders — tags collect placeholders separately from the static query text so values are properly parameterised.

  • Internationalisation — libraries like lit-html and styled-components parse the template at runtime to produce DOM, CSS or translated text.

  • Pretty error formatting — frameworks tag error templates to add ANSI colour codes for the terminal.

The most common tag in the wild is String.raw — it gives you the string with backslash escapes preserved:

JS
const path = String.raw`C:\Users\Ada\file.txt`;
console.log(path);
C:\Users\Ada\ile.txt
Things that surprise people
  • Template literals are strings — the result of evaluating one is just a regular "foo". There is no special type.

  • Interpolation calls String(...) on the value. ${obj} will yield "[object Object]" unless obj has a toString method.

  • ${null} becomes "null" and ${undefined} becomes "undefined". Filter or default these before interpolating if you care.

  • You can interpolate inside another template literal, but the editor highlighting can suffer. Pull complex pieces into local variables.

  • Tagged templates can return anything, not just a string — many DSL libraries return DOM nodes or objects.

Backticks are the default tool for any string you build dynamically. Reach for single or double quotes mostly for short static text — JSON keys, error literals, regex patterns — where the extra power of a template literal would just be noise.