prefer-template-literal
Prefer template literals over string concatenation with runtime values
Keywords: template literal, string concatenation, plus operator, interpolation, ESLint rule, ES2015, auto-fix, LLM-optimized
Prefer template literals over string concatenation with + when at least one operand is a runtime value. This rule is part of eslint-plugin-modernization.
Quick Summary
| Aspect | Details |
|---|---|
| Severity | Warning (modern JavaScript) |
| Auto-Fix | ✅ Yes (replaces + chain with a template literal) |
| Category | Modernization |
| ESLint MCP | ✅ Optimized for ESLint MCP integration |
| Best For | ES2015+ codebases, cleaner string building |
Rule Details
Template literals with string interpolation are more readable and less error-prone than concatenating strings with +. This rule flags any + expression that mixes string literals with runtime values (variables, member expressions, function calls, etc.) and rewrites the entire chain as a single template literal.
Pure string-literal concatenation ("foo" + "bar") and numeric addition (1 + 2) are intentionally ignored.
Why This Matters
| Issue | Impact | Solution |
|---|---|---|
| 📖 Readability | Mixed + chains are hard to scan | Use template literals with interpolation |
| 🐛 Implicit coercion | + coerces operands unpredictably | Interpolation is unambiguous |
| 🔄 Consistency | Multiple string-building styles in codebase | Standardize on template literals |
Examples
❌ Incorrect
// String concatenation with runtime value
const greeting = "Hello, " + name + "!";
const path = "/api/v1/" + resource + "/" + id;
const message = "Error: " + err.message;✅ Correct
// Template literal with interpolation
const greeting = `Hello, ${name}!`;
const path = `/api/v1/${resource}/${id}`;
const message = `Error: ${err.message}`;
// Pure string concat is fine (no runtime values)
const url = "https://" + "example.com";Auto-fix
ESLint can fix this automatically. Running eslint --fix rewrites the concatenation chain into a single template literal — no manual edits required.
Before
const msg = "Hello, " + name + "!";
const path = "/api/v1/" + resource + "/" + id;After
const msg = `Hello, ${name}!`;
const path = `/api/v1/${resource}/${id}`;The fixer joins all operands into one template literal, promoting any plain string segments to static parts and wrapping runtime values in ${...} expressions.
Configuration Examples
Basic Usage
{
rules: {
'modernization/prefer-template-literal': 'warn'
}
}Related Rules
prefer-at- Modern array element accessprefer-event-target- Modern event handling
Further Reading
- Template literals - MDN - MDN reference
- ES2015 Features - ECMAScript specification
Known False Negatives
The following patterns are not detected due to static analysis limitations:
Dynamic Variable References
Why: Static analysis cannot always determine whether a variable holds a string or a number at the point of + use.
// ❌ NOT DETECTED - ambiguous operand type
const result = a + b; // could be numeric additionMitigation: Add TypeScript types so the linter has enough signal, or review concatenation chains manually.
Imported Values
Why: When values come from imports, the rule cannot analyze their origin or construction.
// ❌ NOT DETECTED - Value from import
import { prefix } from './constants';
const path = prefix + resource; // Cross-file origin not trackedMitigation: Ensure imported string values are typed as string in TypeScript so the rule can flag the concatenation.
Did this rule catch something? Star the repo to get new CWE coverage as we ship it — or follow the AI-code-security benchmarks behind these rules.