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
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 \$
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:
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
Escapes still work
`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
// 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)};
`;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.
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 HTML —
html\${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-htmlandstyled-componentsparse 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:
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]"unlessobjhas atoStringmethod.${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.