Template literals are a feature of ES2015 that you can’t ignore. Indeed, it add many useful things. For example, you can :
- Multiline
- Insert variables and/or expressions inside strings
- Create tagged templates
First, multiline
Before, with classics strings, the only way to do multiline was to add the break line character. And to make it lisible, generally, we used concatenation. It might be something like :
const uglyString = "A useless paragraph" + "\nAnother useless paragraph";
Let’s see the new code for the same text, with template literals :
const betterString = `A useless paragraph Another useless paragraph`;
Better, right? 🙂
Variables and expressions with template literals
With classics strings, to use variable, you must only use concatenation :
const name = "Kévin"; const dynamicString = "Hello, " + name + "," + "\nHow are you today?";
Verbose, and ugly right? So let’s take a look to the same with template literals :
const name = "Kévin"; const dynamicString = `Hello, ${name}, How are you today?`;
As you can see, it’s really clean, really better. Moreover, you can add more complex expressions instead of variables. Look at the following :
const users = [ { name: 'Julian', age: 16 }, { name: 'Yoan', age: 28 }, ]; const getWelcomeMessage = ({ name, age }) => `Hello ${name}, You're so ${age < 21 ? 'cute, little child' : 'strong, big guy'}? `; console.log(getWelcomeMessage(user[0])); // Hello Julian, // You're so cute, little child? console.log(getWelcomeMessage(user[1])); // Hello Yoan, // You're so strong, big guy?

Another awesome feature : tagged templates
Maybe have you already seen syntax like variable`text`
? For example, a well-known javascript library use them, it’s styled-components.
Okay, I will explain you how it work, but sometimes, examples are better than words.
function myTag() { return 'Bye!'; } console.log(myTag`Hello!`);
In your opinion, what text will be displayed in the console? “Hello!”? You looooooose.
“Bye!” will be displayed! With tagged templates, the value of your string will be the return of the tag function.
Tagged template arguments
How to retrieve string from a tagged template? You have the first argument, it’s an array of strings, and it contains pieces of string exploded by expressions.
So, consider the following template strings :
`Hello ${'Kévin'}, how are you, during this ${'sunny'} day?`
In this example, the string will be divided like :
['Hello ', ', how are you, during this ', ' day?']
It will be the value of the first argument.
Others arguments will be passed to the function : it’s resolved expressions. So in this example, it will be 'Kévin'
and 'sunny'
.
But, don’t believe me, test it yourself!
const tag = (strings, firstname, weather) => { console.log(strings); // ['Hello ', ', how are you, during this ', ' day?'] console.log(firstname); // Kévin console.log(weather); // weather }; tag`Hello ${'Kévin'}, how are you, during this ${'sunny'} day?`
What? It’s not exactly what you see?! You’re right.

strings
in the consoleAs you can see, there is a raw
array at the end of the line.
Raw strings in tagged templates
So, we will log this array. Consider this code :
function tag(strings) { console.log(strings[0]); console.log(strings.raw[0]); } tag`string text line 1 \n string text line 2`;
The result of these console.log
will be similars but with raw
, special characters will not be escaped. The result :

Advanced template literals
For fun, now, let’s try with a more complex example. We will try to create a similar/ver light function as styled-components, but without react. It will generate pure html, not React components, and it will do it with template literals.
const styled = (() => { let id = 0; let allStyles = []; // Generate an unique className const generateClassName = () => `s${id++}`; // We just rebuild the css from the original string const interpolate = (strings, vars) => strings.map((string, index) => { return string + (vars[index] ? vars[index] : ''); }).join(''); // Minify final css const minifyCss = css => css.replace(/(\r\n|\n|\r)/g, '') .replace(/(\s+)/g, ' ') .replace(/;}/g, '}') .replace(/{\s/g, '{') const propsToString = props => { return Object.keys(props).map(key => ` ${key}="${props[key]}"`) .join(''); }; // We concat styles for all styled components const renderCss = () => { const css = minifyCss( allStyles .map(({ css, className }) => `.${className}{${css}}`) .join('') ); return `<style>${css}</style>`; }; // The proxy is here to let us use fake properties on the styled object // So, we can use all html tags as we want return new Proxy({}, { get: (target, tagName) => function () { if (tagName === 'renderCss') { return renderCss(); } const [strings, ...vars] = arguments; const generatedClassName = generateClassName(); const css = interpolate(strings, vars); allStyles = [ ...allStyles, { css, className: [generatedClassName] } ] return (children, properties = {}) => { const { className = '', ...props } = properties; const classProp = `class="${generatedClassName}${className && ` ${className}`}"`; const otherProps = propsToString(props); return `<${tagName} ${classProp}${otherProps}>${children}</${tagName}>`; }; } }) })(); const App = styled.div` margin-top: 10px; background-color: ${'blue'}; `; const Hello = styled.span` color: ${'red'}; font-weight: bold; `; App( Hello(`Hello ${'World'}`), { id: 'app' } ) + styled.renderCss()
You can test it on jsfiddle