LWC Complex Expressions in Spring '26: What's New
If you've been writing Lightning Web Components for any length of time, you've probably written a one-line getter just to format a date, build a CSS class string, or check whether two values match. I know I have. Dozens of them. Maybe hundreds.
Spring '26 changes that. Salesforce shipped Complex Template Expressions as a beta feature, and it's the kind of update that quietly changes how you build components day to day. You can now write actual JavaScript expressions inside your HTML templates: ternary operators, math, string concatenation, logical operators, all of it. No more getter graveyard cluttering up your .js files.
I want to walk through what's actually new, what it looks like in practice, what's still off-limits, and a few opinions on when to reach for it (and when not to).
What the LWC Template Could Do Before
Up until Spring '26, LWC templates were intentionally simple. You could bind a property, call a getter, use lwc:if for conditional rendering, and that was about it. If you wanted to do anything beyond {firstName}, you had to drop into JavaScript and write a getter.
Want to display a total with tax? Getter. Want to show "Equals" or "Not equals" based on two values? Getter. Want to concatenate a first and last name? You guessed it, getter.
Here's what that looked like in practice:
// myComponent.js
export default class MyComponent extends LightningElement {
quantity = 5;
price = 10;
taxRate = 0.08;
get totalWithTax() {
return (this.quantity * this.price) * (1 + this.taxRate);
}
}
<!-- myComponent.html -->
<template>
<p>Total: {totalWithTax}</p>
</template>
For one value, fine. For ten of them, you've got a JavaScript file full of trivial computations, and finding the actual business logic gets harder. The original design philosophy was sound: keep templates dumb, keep logic testable. But in practice it created friction for the simplest UI work.
If you want a refresher on getters, properties, and how reactive bindings work in LWC, the glossary at salesforcedictionary.com has solid breakdowns that I find myself sending to junior devs more often than I'd like to admit.
What Complex Expressions Actually Let You Do
Here's the same component rewritten with complex expressions:
<!-- myComponent.html -->
<template>
<p>Total: {quantity * price * (1 + taxRate)}</p>
</template>
That's it. The getter is gone. The arithmetic happens right where it's displayed.
The supported expression set covers most of what you'd reach for in a typical template:
-
Arithmetic:
{price * quantity},{count + 1},{100 - discount} -
String concatenation:
{firstName + ' ' + lastName}or template literals like{`Hello, ${userName}!`} -
Ternary operators:
{isActive ? 'Active' : 'Inactive'} -
Nested ternaries:
{score >= 90 ? 'A' : score >= 80 ? 'B' : 'C'} -
Logical operators:
{isAdmin && canEdit}or{primary || fallback} -
Comparisons:
{value === expected ? 'Match' : 'No match'} -
Method calls on bound values:
{name.toUpperCase()}or{message.length}
You can also use these expressions in the lwc:if directive, which means you can finally write things like <template lwc:if={count > 5}> without a getter named isCountGreaterThanFive.
A Real Example: Status Badges Without Getters
Let me show a slightly more interesting use case. Say you've got an opportunity component and you want to render a status badge with the right color based on stage and probability. Before Spring '26, you'd write three or four getters: one for the label, one for the icon, one for the variant, one for the title attribute.
With complex expressions, your template can carry that logic inline:
<template>
<lightning-badge
label={stage === 'Closed Won' ? 'Won' : stage === 'Closed Lost' ? 'Lost' : 'Open'}
icon-name={probability > 75 ? 'utility:success' : probability > 25 ? 'utility:warning' : 'utility:error'}
variant={probability > 50 ? 'success' : 'warning'}>
</lightning-badge>
<p lwc:if={amount > 100000}>High-value opportunity</p>
</template>
The JavaScript file just holds the data. The template handles presentation. That's the split a lot of us have wanted for years.
I'll be honest though: this can absolutely get out of hand. A six-level nested ternary in a template is going to age like milk. Salesforce's own guidance is to keep complex business logic in JavaScript methods and use template expressions only for presentation. I'd second that. If you find yourself reaching for the comma operator in a template, stop and write a getter.
The Limitations and the Beta Asterisk
A few things to keep in mind before you go refactoring your whole org.
It's still a beta. Salesforce explicitly says don't use complex template expressions in production. Beta features can change behavior or get pulled. If you're shipping to a customer org tomorrow, hold off. If you're prototyping or working in a sandbox, go for it.
Not every JS expression is allowed. You can't use assignment (=, +=), increment/decrement (++, --), new, delete, comma operator, or anything that mutates state. The point is to compute display values, not to run side effects from your template. That's a feature, not a bug.
No statements, only expressions. You can't write if/else blocks, for loops, or var declarations inside {...}. Use lwc:if and lwc:for:each for control flow.
Performance is the same. The LWC compiler still produces optimized rendering code under the hood. Complex expressions don't add re-renders or change how reactivity works. If a property the expression depends on changes, the expression re-evaluates. That's it.
Tooling support is improving. As of Spring '26, the official LWC extension for VS Code understands complex expressions and gives you syntax highlighting and basic error checking. ESLint rules from @lwc/eslint-plugin-lwc are getting updates to lint these too.
When to Use Complex Expressions vs. Getters
Here's my rough rule of thumb after a few weeks of playing with this in sandbox.
Reach for an inline expression when the logic fits on one line, when it's pure presentation (formatting, simple math, label selection), when you're computing a value used only in one place, and when the expression won't need a unit test.
Stick with a getter when the logic spans multiple lines or branches, when you need to call it from multiple places, when it encodes a business rule worth testing, or when a future dev would benefit from the named abstraction.
For example: {amount.toLocaleString('en-US', { style: 'currency', currency: 'USD' })} works inline, but if you're using that in fifteen places, a getter named formattedAmount reads better and is easier to change in one spot. If you ever need a quick reference for terms like "getter," "reactive property," or any of the other LWC vocabulary that comes up here, salesforcedictionary.com keeps a clean glossary.
How to Try It in Your Sandbox
Spring '26 hits sandboxes starting January 9, 2026, and rolls to production on February 13 and February 20. To play with complex expressions:
- Spin up a Spring '26 sandbox or a scratch org with the right API version (62.0 or higher).
- In your
.htmlfile, just start writing the expressions. There's no flag to flip and no@apidecorator to add. - Run the Local Dev Server if you're working locally, since it now supports the new expression set.
- Watch the browser console. The compiler will warn loudly if you use an unsupported expression like
=or++.
If you want to learn this hands-on, build a small "shopping cart line item" component. It's a great test bed: total with tax, conditional discount label, formatted currency, status icon based on stock level. You'll touch every kind of expression in about thirty minutes. For broader Spring '26 terminology and feature definitions, salesforcedictionary.com is a handy bookmark.
Wrapping Up
Complex template expressions aren't going to revolutionize how you architect a Salesforce app, but they will quietly delete a lot of busywork from your daily LWC writing. The getter graveyard shrinks. Templates become more expressive. Component files get easier to read.
Just remember: it's still a beta as of Spring '26, so production deployments need to wait. Use it in sandboxes, prototypes, and demos. Watch the release notes for GA. And resist the urge to write nested ternaries that read like regex.
What features from Spring '26 are you most excited about? Are you already using complex expressions in your components, or holding off until GA? Drop a comment below, I'd love to hear how other teams are approaching it.
Top comments (0)