Template Literals in JavaScript: The Modern Way to Work with Strings
Introduction
If you've been writing JavaScript for a while, you've probably spent time building strings by concatenating multiple pieces together. It can get messy, error-prone, and hard to read. Template literals are a modern JavaScript feature that completely transforms how you work with strings. They make your code cleaner, more readable, and less prone to mistakes. In this blog, we'll explore template literals in detail and see why they've become the preferred way to build strings in modern JavaScript.
1. Problems with Traditional String Concatenation
Before template literals, JavaScript developers had to use concatenation to build strings dynamically. This approach has several problems.
The Basic Problem: Mixing Strings and Variables
const name = "Rajeev";
const age = 25;
const city = "Mumbai";
// Old way: Using concatenation
const message = "Hello, my name is " + name + " and I am " + age + " years old. I live in " + city + ".";
console.log(message); // Hello, my name is Rajeev and I am 25 years old. I live in Mumbai.
While this works, it's tedious and error-prone. You have to carefully count your quotes and plus signs.
Problem 1: Hard to Read
const product = "Laptop";
const price = 50000;
const discount = 10;
const finalPrice = price - (price * discount / 100);
// This is hard to read
const receipt = "Product: " + product + "\nPrice: Rs." + price + "\nDiscount: " + discount + "%\nFinal Price: Rs." + finalPrice;
console.log(receipt);
The string gets lost in a sea of plus signs and quotes.
Problem 2: Easy to Make Mistakes
const firstName = "Ananya";
const lastName = "Sharma";
// Forgot a space!
const fullName = firstName + "" + lastName; // "AnanyaSharma"
// Another mistake
const greeting = "Welcome" + firstName; // "WelcomAnanya" - typo in variable name
Small typos can go unnoticed and cause bugs.
Problem 3: Escaping Quotes
// Escaping gets messy
const quote = "She said, \"Hello, how are you?\" to me.";
console.log(quote); // She said, "Hello, how are you?" to me.
// With single quotes inside double quotes
const message = "It's a beautiful day";
console.log(message); // It's a beautiful day
// But what if you mix them?
const mixed = "He said, \"It's a beautiful day\" to me.";
console.log(mixed); // He said, "It's a beautiful day" to me.
You have to escape quotes with backslashes, making the code look messy.
Problem 4: Multi-line Strings Are Awkward
// Trying to create a multi-line string
const poem = "Roses are red,\nViolets are blue,\nSugar is sweet,\nAnd so are you.";
console.log(poem);
// Or you have to break it into multiple lines
const multiLine = "This is line 1 " +
"This is line 2 " +
"This is line 3";
console.log(multiLine);
Both approaches are awkward and require manual line breaks or concatenation.
Problem 5: Conditional Strings Are Complex
const user = "Priya";
const isAdmin = true;
const itemCount = 5;
// Building conditional strings with concatenation is verbose
const message = "Hello " + user + "! " +
(isAdmin ? "You are an administrator. " : "") +
"You have " + itemCount + " items.";
console.log(message); // Hello Priya! You are an administrator. You have 5 items.
Complex expressions inside string concatenation are hard to follow.
2. Template Literal Syntax
Template literals use backticks (`) instead of quotes, and they solve all the problems we just discussed.
Basic Syntax:
// Old way with quotes
const simple = "Hello World";
// New way with backticks (template literal)
const template = `Hello World`;
console.log(simple); // Hello World
console.log(template); // Hello World
Both produce the same result, but template literals have powerful features that regular strings don't have.
Backticks Are Key:
// These are three different things:
// Regular string with double quotes
const double = "Hello";
// Regular string with single quotes
const single = 'Hello';
// Template literal with backticks
const template = `Hello`;
// Template literals have special powers that others don't
Remember: Use backticks (`) for template literals, not regular quotes.
When to Use Each:
// Use regular strings for simple text
const name = "Deepak";
// Use template literals when you need to embed variables or multi-line text
const greeting = `Hello, ${name}!`;
// Or when building complex strings
const html = `
<div class="card">
<h1>${name}</h1>
</div>
`;
3. Embedding Variables in Strings
This is the most powerful feature of template literals. You can embed variables and expressions directly inside the string using ${...} syntax.
Basic Variable Embedding:
const firstName = "Vikram";
const lastName = "Singh";
const age = 28;
// The old way
const oldWay = "Name: " + firstName + " " + lastName + ", Age: " + age;
// The new way with template literals
const newWay = `Name: \({firstName} \){lastName}, Age: ${age}`;
console.log(newWay); // Name: Vikram Singh, Age: 28
Much cleaner! The variables appear directly in the string where you need them.
Embedding Expressions:
You can put any JavaScript expression inside ${}, not just variables:
const price = 1000;
const quantity = 5;
// Simple arithmetic
const total = `Total cost: Rs.${price * quantity}`;
console.log(total); // Total cost: Rs.5000
// Method calls
const name = "ananya sharma";
const greeting = `Hello, ${name.toUpperCase()}!`;
console.log(greeting); // Hello, ANANYA SHARMA!
// Ternary operators
const age = 21;
const ageGroup = `Age group: ${age >= 18 ? "Adult" : "Minor"}`;
console.log(ageGroup); // Age group: Adult
// Function calls
function getDiscount(amount) {
return amount * 0.1;
}
const originalPrice = 500;
const discount = getDiscount(originalPrice);
const finalPrice = `Original: Rs.\({originalPrice}, Discount: Rs.\){discount}, Final: Rs.${originalPrice - discount}`;
console.log(finalPrice); // Original: Rs.500, Discount: Rs.50, Final: Rs.450
Complex Expressions:
const student = {
name: "Shreya",
marks: 85,
subject: "Mathematics"
};
// Accessing object properties inside template literal
const result = `\({student.name} scored \){student.marks} in ${student.subject}`;
console.log(result); // Shreya scored 85 in Mathematics
// Array operations
const fruits = ["Apple", "Banana", "Mango"];
const fruitList = `Fruits: ${fruits.join(", ")}`;
console.log(fruitList); // Fruits: Apple, Banana, Mango
// Nested template literals
const items = 3;
const itemList = `You have \({items} items: \){items > 0 ? `${items} things` : "nothing"}`;
console.log(itemList); // You have 3 items: 3 things
Escaping in Template Literals:
// Backticks don't need escaping inside template literals
const quote = `She said, "Hello!" to me.`;
console.log(quote); // She said, "Hello!" to me.
// Single quotes also don't need escaping
const message = `It's a beautiful day`;
console.log(message); // It's a beautiful day
// But if you need a backtick, you must escape it
const code = `This is a backtick: \` symbol`;
console.log(code); // This is a backtick: ` symbol
// Backslashes
const path = `C:\\Users\\Name\\Documents`;
console.log(path); // C:\Users\Name\Documents
4. Multi-line Strings
One of the best features of template literals is how easy it is to create multi-line strings.
Multi-line Without Line Breaks:
// Old way: concatenation with \n
const oldPoem = "Roses are red,\nViolets are blue,\nSugar is sweet,\nAnd so are you.";
// New way: just press Enter inside template literal
const newPoem = `Roses are red,
Violets are blue,
Sugar is sweet,
And so are you.`;
console.log(newPoem);
// Output:
// Roses are red,
// Violets are blue,
// Sugar is sweet,
// And so are you.
The template literal preserves the actual line breaks in your code.
Creating HTML Strings:
const productName = "Laptop";
const price = 50000;
const inStock = true;
const html = `
<div class="product">
<h2>${productName}</h2>
<p class="price">Rs.${price}</p>
<p class="status">${inStock ? "In Stock" : "Out of Stock"}</p>
</div>
`;
console.log(html);
// Output:
// <div class="product">
// <h2>Laptop</h2>
// <p class="price">Rs.50000</p>
// <p class="status">In Stock</p>
// </div>
Creating JSON:
const user = {
name: "Arjun",
age: 24,
email: "arjun@example.com"
};
const jsonString = `
{
"name": "${user.name}",
"age": ${user.age},
"email": "${user.email}"
}
`;
console.log(jsonString);
Creating SQL Queries:
const userId = 5;
const userName = "Priya";
const userEmail = "priya@example.com";
const sqlQuery = `
INSERT INTO users (id, name, email)
VALUES (\({userId}, '\){userName}', '${userEmail}')
`;
console.log(sqlQuery);
Preserving Indentation:
const menu = `
Menu
====
1. Coffee Rs.100
2. Tea Rs.50
3. Juice Rs.80
4. Water Rs.20
`;
console.log(menu);
// Output preserves all the spacing
5. Use Cases in Modern JavaScript
Template literals are used everywhere in modern JavaScript. Let's explore practical use cases.
Use Case 1: Logging and Debugging
const user = "Rajesh";
const action = "logged in";
const timestamp = new Date().toLocaleString();
// Clear, readable logging
console.log(`\({user} \){action} at ${timestamp}`);
// Output: Rajesh logged in at 3/26/2026, 2:30:45 PM
Use Case 2: Error Messages
const errorCode = 404;
const resource = "User Profile";
const method = "GET";
// Before: Hard to read
const oldError = "Error " + errorCode + ": " + method + " request for " + resource + " failed";
// After: Clear and readable
const newError = `Error \({errorCode}: \){method} request for ${resource} failed`;
console.log(newError); // Error 404: GET request for User Profile failed
Use Case 3: Building Dynamic URLs
const baseUrl = "https://api.example.com";
const endpoint = "users";
const userId = 123;
const apiUrl = `\({baseUrl}/\){endpoint}/${userId}`;
console.log(apiUrl); // https://api.example.com/users/123
// With query parameters
const searchTerm = "javascript";
const limit = 10;
const searchUrl = `\({baseUrl}/search?q=\){searchTerm}&limit=${limit}`;
console.log(searchUrl); // https://api.example.com/search?q=javascript&limit=10
Use Case 4: Building Dynamic CSS
const primaryColor = "#FF6B6B";
const fontSize = "16px";
const fontFamily = "Arial";
const styles = `
body {
font-family: ${fontFamily};
font-size: ${fontSize};
color: ${primaryColor};
}
`;
console.log(styles);
Use Case 5: Creating Reusable Components
function createButton(text, color, size) {
return `
<button style="background-color: \({color}; padding: \){size};">
${text}
</button>
`;
}
const btn1 = createButton("Click Me", "blue", "10px");
const btn2 = createButton("Submit", "green", "15px");
console.log(btn1);
// Output:
// <button style="background-color: blue; padding: 10px;">
// Click Me
// </button>
Use Case 6: Building Data Displays
const students = [
{ name: "Aman", marks: 85 },
{ name: "Bhavna", marks: 92 },
{ name: "Chirag", marks: 78 }
];
const report = `
STUDENT REPORT
==============
\({students.map(s => `\){s.name.padEnd(15)} - ${s.marks}/100`).join("\n")}
`;
console.log(report);
// Output:
// STUDENT REPORT
// ==============
// Aman - 85/100
// Bhavna - 92/100
// Chirag - 78/100
Use Case 7: Configuration Objects
const appName = "MyApp";
const version = "1.0.0";
const environment = "production";
const apiKey = "secret123";
const config = `
{
"app": "${appName}",
"version": "${version}",
"environment": "${environment}",
"apiKey": "${apiKey}",
"timestamp": "${new Date().toISOString()}"
}
`;
console.log(config);
6. Comparison: Old vs New
Let's see side-by-side comparisons of old string concatenation versus template literals.
Example 1: Simple Greeting
// OLD WAY
const firstName = "Priya";
const lastName = "Sharma";
const greeting_old = "Hello, " + firstName + " " + lastName + "!";
// NEW WAY
const greeting_new = `Hello, \({firstName} \){lastName}!`;
console.log(greeting_old); // Hello, Priya Sharma!
console.log(greeting_new); // Hello, Priya Sharma!
Example 2: Calculation
const subtotal = 1000;
const tax = 100;
const shipping = 50;
// OLD WAY
const receipt_old = "Subtotal: Rs." + subtotal + "\nTax: Rs." + tax + "\nShipping: Rs." + shipping + "\nTotal: Rs." + (subtotal + tax + shipping);
// NEW WAY
const receipt_new = `
Subtotal: Rs.${subtotal}
Tax: Rs.${tax}
Shipping: Rs.${shipping}
Total: Rs.${subtotal + tax + shipping}
`;
console.log(receipt_old);
console.log(receipt_new);
Example 3: Building HTML
const title = "Welcome";
const content = "This is the main content";
const footer = "Copyright 2026";
// OLD WAY
const html_old = "<div>" +
"<h1>" + title + "</h1>" +
"<p>" + content + "</p>" +
"<footer>" + footer + "</footer>" +
"</div>";
// NEW WAY
const html_new = `
<div>
<h1>${title}</h1>
<p>${content}</p>
<footer>${footer}</footer>
</div>
`;
console.log(html_old);
console.log(html_new);
Readability Comparison:
| Aspect | Old Concatenation | Template Literals |
|---|---|---|
| Readability | Hard to follow | Easy to read |
| Mistakes | Easy to make errors | Less error-prone |
| Multi-line | Awkward with \n or + | Natural |
| Expressions | Breaks flow | Inline with ${} |
| Maintenance | Difficult | Easy |
7. Tagged Template Literals
Advanced feature: You can tag template literals with a function to process them in a custom way.
Basic Tagged Template:
function highlight(strings, ...values) {
console.log("Strings:", strings);
console.log("Values:", values);
let result = "";
for (let i = 0; i < strings.length; i++) {
result += strings[i];
if (i < values.length) {
result += "[HIGHLIGHTED: " + values[i] + "]";
}
}
return result;
}
const name = "Vikram";
const age = 25;
const output = highlight`My name is \({name} and I am \){age} years old`;
console.log(output);
// Output: My name is [HIGHLIGHTED: Vikram] and I am [HIGHLIGHTED: 25] years old
Practical Example: HTML Sanitization
function sanitizeHTML(strings, ...values) {
let result = "";
for (let i = 0; i < strings.length; i++) {
result += strings[i];
if (i < values.length) {
// Escape HTML special characters in values
const escaped = String(values[i])
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """);
result += escaped;
}
}
return result;
}
const userInput = "<script>alert('hacked')</script>";
const html = sanitizeHTML`<p>${userInput}</p>`;
console.log(html); // <p><script>alert('hacked')</script></p>
8. Common Patterns and Best Practices
Pattern 1: Conditional Rendering
const isLoggedIn = true;
const username = "Sneha";
const status = `
\({isLoggedIn ? `Welcome back, \){username}!` : "Please log in."}
`;
console.log(status); // Welcome back, Sneha!
Pattern 2: Mapping Arrays
const items = ["Bread", "Milk", "Eggs"];
const list = `
Shopping List:
\({items.map((item, index) => `\){index + 1}. ${item}`).join("\n")}
`;
console.log(list);
// Output:
// Shopping List:
// 1. Bread
// 2. Milk
// 3. Eggs
Pattern 3: Formatting Numbers and Dates
const amount = 5000;
const date = new Date();
const receipt = `
Transaction Date: ${date.toLocaleDateString()}
Amount: Rs.${amount.toLocaleString()}
Time: ${date.toLocaleTimeString()}
`;
console.log(receipt);
// Output:
// Transaction Date: 3/26/2026
// Amount: Rs.5,000
// Time: 2:30:45 PM
Pattern 4: Default Values with OR operator
const user = { name: "Raj" }; // no email
const profile = `
Name: ${user.name}
Email: ${user.email || "Not provided"}
Phone: ${user.phone || "Not provided"}
`;
console.log(profile);
// Output:
// Name: Raj
// Email: Not provided
// Phone: Not provided
Pattern 5: Nested Template Literals
function renderUser(user) {
return `<div class="user">${user.name}</div>`;
}
const users = [
{ name: "Arjun" },
{ name: "Bhavna" }
];
const html = `
<div class="users">
${users.map(user => renderUser(user)).join("")}
</div>
`;
console.log(html);
9. Real-World Example: Building a Blog Post Component
Let's create a practical example that combines multiple features:
function createBlogPost(post) {
const { title, author, date, content, tags, likes, comments } = post;
const formattedDate = new Date(date).toLocaleDateString();
return `
<article class="blog-post">
<div class="header">
<h1>${title}</h1>
<div class="meta">
<span class="author">By ${author}</span>
<span class="date">${formattedDate}</span>
</div>
</div>
<div class="content">
${content}
</div>
<div class="tags">
${tags.length > 0 ? `
<strong>Tags:</strong>
\({tags.map(tag => `<span class="tag">#\){tag}</span>`).join(" ")}
` : ""}
</div>
<div class="footer">
<span class="likes">
\({likes} \){likes === 1 ? "like" : "likes"}
</span>
<span class="comments">
\({comments} \){comments === 1 ? "comment" : "comments"}
</span>
</div>
</article>
`;
}
// Usage
const blogPost = {
title: "Understanding Template Literals",
author: "Ashish Singodiya",
date: "2026-03-26",
content: "Template literals are one of the best features in modern JavaScript...",
tags: ["javascript", "es6", "strings"],
likes: 42,
comments: 7
};
const html = createBlogPost(blogPost);
console.log(html);
10. Performance Consideration
Template literals are not slower than string concatenation. In fact, modern JavaScript engines optimize them equally well.
// All three are equally performant in modern browsers
const a = "Hello " + name;
const b = `Hello ${name}`;
const c = "Hello ".concat(name);
// Use whichever is most readable for your use case
The choice should be based on readability, not performance.
Conclusion
Template literals have revolutionized how we work with strings in JavaScript. Here's a summary of their benefits:
Cleaner Code: Variables are embedded directly where needed
Better Readability: No more confusing chains of + operators
Multi-line Strings: Just press Enter, no need for \n
Fewer Mistakes: Less chance of forgetting quotes or spaces
Powerful Expressions: Anything inside ${} is evaluated
Modern Standard: Supported in all modern browsers and Node.js
If you're still using string concatenation in 2026, it's time to switch to template literals. They're easier to write, easier to read, and easier to maintain. Start using them in your projects today, and you'll wonder how you ever lived without them.
Template literals aren't just a nice feature to have, they're a modern standard that every JavaScript developer should be comfortable using. Make them a habit, and your code will be cleaner and more professional.




