JavaScript Template Literals Table
| Pattern | What it does | Field note |
|---|---|---|
`Hello ${name}` | Embed expressions in strings | Backticks, not quotes - ${} is the slot |
`line1\nline2` or real newline | Multi-line strings | Real line breaks in the source ARE the string |
`${a + b}` | Any expression inside | Calls, ternaries, arithmetic - full expression power |
`Total: ${n.toFixed(2)}` | Method calls inside | Nested backticks escape as \` - rare |
String.raw`C:\path` | No escape processing | Backslashes stay literal - regex and Windows paths |
tagged`template` | Custom processing function | tag receives strings array + values - i18n and DSLs |
`${obj}` | Calls toString implicitly | [object Object] surprise - destructure or JSON.stringify first |
Template literals are backtick strings with superpowers: ${} embeds any expression, real newlines need no escape, and tagged templates hand the pieces to a custom function - the mechanism under styled-components and i18n libraries. The table below is the working seven.
Bottom line: three upgrades over plain quotes - interpolation, legal multi-line source, and tagged processing. The classic bug is the last row: interpolating an object prints [object Object], because object-to-string has nothing better to offer. Destructure the fields into the template, or JSON.stringify(obj) explicitly - the template only formats what it is handed.
The honest part: two escapes matter. Inside a template, a literal ${ needs an escape (\${) or the engine treats it as an interpolation slot; and nested backticks escape as \` - rare, but it bites when building HTML-in-JS with inline code samples. Plain quotes remain correct for constants: the upgrade pays only when interpolation or line span is real.
How to use
- Switch to backticks when a string gains interpolation or spans lines - the two upgrades that pay immediately.
- Put whole expressions in ${}: calls, ternaries and arithmetic work - but keep complex logic outside and interpolate the result.
- Use String.raw for anything backslash-heavy (regex sources, Windows paths) - the raw tag skips escape processing entirely.
Frequently asked questions
Why does my template print [object Object]?
Because interpolating an object calls its toString method, and the default Object.prototype.toString has nothing better to return than that placeholder string. The fixes: interpolate the specific fields (${user.name} instead of ${user}), or JSON.stringify(user) when the whole object is the point. Arrays interpolate better (their toString joins with commas) but still lose structure - explicit is always clearer.
How do I write a literal dollar-brace in a template literal?
Escape the dollar: \${notInterpolated} renders as ${notInterpolated}. You only need this when writing documentation, code samples or template generators INSIDE a template literal - the engine scans for ${ to start interpolation, and the backslash hides it. Same story for the backtick itself: \` escapes a nested backtick, which appears when generating code samples that contain templates of their own.
What are tagged templates actually for?
A tag is a function that receives the string pieces and the interpolated values SEPARATELY, and returns whatever it wants - sanitized HTML (the tag escapes values while keeping structure), i18n translation (the tag looks up the static string in a dictionary), or DSL parsing (styled-components turns CSS text into class names). The raw strings array also reaches the tag, so String.raw is itself a built-in tag: String.raw\n stays two characters.
Do template literals replace string concatenation everywhere?
For readability, mostly yes - ${name} reads in order while 'Hello ' + name + '!' scatters the variables between quotes. The honest exceptions: plain constants without interpolation gain nothing from backticks, and very long template-built HTML can hide structure that JSX or template functions would make explicit. Performance differences are negligible in modern engines - choose by readability and interpolate deliberately.