Skip to content
JavaScript js strings 3 min read

Template Literals

Template literals are strings delimited by backticks (`) instead of single or double quotes. Introduced in ES2015, they let you embed expressions directly inside a string, span multiple lines without escape sequences, and compose readable output without clumsy + concatenation. Once you start using them, plain string addition feels like a relic.

The basics: backticks

A template literal looks like an ordinary string, but it is wrapped in backticks. Inside, you can use single and double quotes freely without escaping them, which alone makes them handy for HTML and JSON-like text.

const plain = `Hello, world`;
const quotes = `She said "yes" and he said 'okay'`;

console.log(plain);
console.log(quotes);

Output:

Hello, world
She said "yes" and he said 'okay'

Interpolation with ${}

The headline feature is interpolation. Anything inside ${ ... } is evaluated as a JavaScript expression and its result is converted to a string and spliced into place. This replaces the noisy concatenation pattern that older code relied on.

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

// Old way
const oldWay = "Hello " + name + ", you are " + age + " years old.";

// Template literal
const newWay = `Hello ${name}, you are ${age} years old.`;

console.log(newWay);

Output:

Hello Ada, you are 36 years old.

The placeholder accepts any expression, not just variables — arithmetic, function calls, property access, and ternaries all work.

const price = 19.99;
const qty = 3;
const user = { isVip: true };

console.log(`Total: $${(price * qty).toFixed(2)}`);
console.log(`Welcome ${user.isVip ? "VIP" : "guest"}!`);
console.log(`In stock: ${["a", "b", "c"].length} items`);

Output:

Total: $59.97
Welcome VIP!
In stock: 3 items

Tip: ${} calls String() on its result. An object becomes [object Object] unless it defines toString(), and an array is joined with commas. Be explicit (JSON.stringify(obj)) when you want structured output.

Multiline strings

Inside backticks, newlines are preserved literally. There is no need for \n or string concatenation across lines, which makes templates ideal for emails, SQL, and markup.

const message = `Dear customer,

Your order has shipped.
Track it anytime in your account.

— The Team`;

console.log(message);

Output:

Dear customer,

Your order has shipped.
Track it anytime in your account.

— The Team

Beware that leading indentation counts as part of the string. If you indent a template to match your code, those spaces appear in the output. Trim or dedent when whitespace matters.

Embedded expressions and nesting

Because each ${} is a full expression, you can nest template literals inside one another. This is common when building markup from arrays with .map().

const items = ["Coffee", "Tea", "Juice"];

const html = `<ul>
${items.map((item) => `  <li>${item}</li>`).join("\n")}
</ul>`;

console.log(html);

Output:

<ul>
  <li>Coffee</li>
  <li>Tea</li>
  <li>Juice</li>
</ul>

Nesting is powerful but readability drops fast. If a placeholder grows beyond a small expression, compute the value into a named variable first.

Readability vs concatenation

The table below contrasts the two approaches across common needs.

NeedConcatenation (+)Template literal
Insert a variable"Hi " + name`Hi ${name}`
Mix quotesescape with \"use quotes freely
Multiline text"a\n" + "b"literal newline
Run an expression"x" + (a * b)`x${a * b}`
Type coercionmanual String(x)automatic

Template literals win on clarity in almost every case. The main exception is appending a single short suffix, where + can read fine — but consistency usually favours backticks.

const product = "Headphones";
const stock = 12;
const summary = `${product} — ${stock > 0 ? `${stock} available` : "out of stock"}`;
console.log(summary);

Output:

Headphones — 12 available

Best practices

  • Reach for template literals by default whenever a string contains a variable or expression.
  • Keep ${} placeholders small; lift complex logic into a named const before interpolating.
  • Use JSON.stringify() for objects and arrays instead of relying on default coercion.
  • Remember that indentation inside multiline templates becomes literal whitespace — dedent intentionally.
  • Prefer .map(...).join("\n") over manual concatenation when generating repeated lines.
  • For HTML built from user input, escape values to avoid injection — template literals do not sanitize.
Last updated June 1, 2026
Was this helpful?