
Imagine you are building a game UI like BGMI.
You want to show a message: “Player Tejas killed Enemy with AKM”
Now you try to build this using normal strings…
The Problem with Traditional String Concatenation
Before ES6, building dynamic strings meant using the + operator to join everything together.
Imagine you're building a player profile for a game:
const name = "Tejas";
const level = 12;
const health = 85;
const message = "Player: " + name + " | Level: " + level + " | Health: " + health + "%";
console.log(message);
// Player: Tejas | Level: 12 | Health: 85%
It works. But look at it quote, plus, variable, plus, quote, plus, variable. You're spending more time managing the syntax than writing the actual message.
Now add a typo, a missing space, or a forgotten + somewhere. Good luck finding it.
The more variables you have, the worse it gets:
const greeting = "Hello, " + firstName + " " + lastName + "! You have " + messages + " new messages and " + notifications + " notifications.";
This is hard to read, easy to break, and painful to edit. There had to be a better way.
Enter Template Literals
ES6 introduced template literals a cleaner way to work with strings.
The syntax uses backticks instead of quotes:
const message = `This is a template literal`;
That's it. Just swap " or ' for `. But the real power comes from what you can do inside them.
Embedding Variables - The ${} Syntax
Instead of breaking the string and using +, you embed variables directly inside the string using ${}:
const name = "Tejas";
const level = 12;
const health = 85;
const message = `Player: \({name} | Level: \){level} | Health: ${health}%`;
console.log(message);
// Player: Tejas | Level: 12 | Health: 85%
Same output. But now the string reads like a sentence. You can see exactly what the final result will look like just by reading it.
No +, no broken quotes, no counting spaces.
It's Not Just Variables - It's Expressions
Anything inside ${} is evaluated as JavaScript. You can put expressions, calculations, function calls anything:
const a = 10;
const b = 5;
console.log(`Sum: ${a + b}`); // Sum: 15
console.log(`Double: ${a * 2}`); // Double: 20
console.log(`Max: ${Math.max(a, b)}`); // Max: 10
const player = { name: "Vivek", level: 8 };
console.log(`\({player.name} is at level \){player.level}`);
// Vivek is at level 8
const isLoggedIn = true;
console.log(`Status: ${isLoggedIn ? "Online" : "Offline"}`);
// Status: Online
You're not limited to simple variables. Whatever JavaScript can evaluate, you can embed.
Multi-line Strings
With regular strings, creating multi-line text was awkward. You had two options both ugly:
Option 1 : using \n:
const bio = "Name: Tejas\nLevel: 12\nHealth: 85%";
Option 2 : concatenating multiple lines:
const bio = "Name: Tejas\n" +
"Level: 12\n" +
"Health: 85%";
Neither of these looks like actual multi-line text. You're simulating it.
With template literals, you just press Enter:
const bio = `Name: Tejas
Level: 12
Health: 85%`;
console.log(bio);
// Name: Tejas
// Level: 12
// Health: 85%
The line breaks are real. What you write is what you get. This is especially useful when building HTML strings or any structured text.
Old Way vs New Way
Let's put both approaches next to each other so the difference is clear.
Building an HTML card old way:
const name = "Tejas";
const level = 12;
const health = 85;
const card = "<div class='player'>" +
"<h2>" + name + "</h2>" +
"<p>Level: " + level + "</p>" +
"<p>Health: " + health + "%</p>" +
"</div>";
Same thing with template literals:
const card = `
<div class="player">
<h2>${name}</h2>
<p>Level: ${level}</p>
<p>Health: ${health}%</p>
</div>
`;
The template literal version looks like actual HTML. You can read it, edit it, and spot mistakes instantly. The old version looks like a puzzle you have to assemble in your head.
Real Use Cases in Modern JavaScript
Template literals aren't just a convenience you'll see them everywhere in modern JS code.
1. Building URLs dynamically
const userId = 42;
const endpoint = `https://api.example.com/users/${userId}/profile`;
2. Logging meaningful messages
const action = "login";
const timestamp = new Date().toLocaleTimeString();
console.log(`[\({timestamp}] User performed: \){action}`);
// [10:45:32 AM] User performed: login
3. Generating HTML dynamically
const players = ["Tejas", "Vivek", "Mahesh"];
const list = `
<ul>
\({players.map(p => `<li>\){p}</li>`).join("")}
</ul>
`;
4. Error messages that actually help
function divide(a, b) {
if (b === 0) {
throw new Error(`Cannot divide ${a} by zero`);
}
return a / b;
}
Much more useful than "Cannot divide by zero" you see the actual value in the error.
Final Thought
Template literals didn't add new capabilities to JavaScript you could always build dynamic strings with +. What they added was clarity.
Code is read far more often than it is written. The less mental effort it takes to read a string, the better. That's the real value of template literals not that they do something new, but that they make something you already do much easier to read and maintain.
Once you start using them, going back to + concatenation will feel like assembling furniture without instructions.

