Stop Typing Boilerplate: A Practical Guide to IntelliJ IDEA Live Templates
IntelliJ IDEA Live Templates turn repetitive boilerplate into a two-keystroke abbreviation. Here's how they work, a logger template built from scratch, and the pitfalls to avoid.
24 Sept 2025, 04:41 UTC

Every Java developer has typed private static final Logger log = LoggerFactory.getLogger(...) hundreds of times. The class name changes, nothing else does, and yet there you are, retyping it. IntelliJ IDEA's Live Templates exist precisely for this: you type a short abbreviation, press Tab, and the IDE expands a full snippet with the cursor parked exactly where you need to type next.
This post walks through how Live Templates actually work, builds one useful template from scratch, and covers the trade-offs worth knowing before your team goes template-happy.
What a Live Template actually is
A Live Template is a reusable snippet bound to an abbreviation and a context. The context matters: a template scoped to Java won't fire in a Kotlin file or inside a comment unless you say so. Each template has three parts:
- Abbreviation — what you type (e.g.,
log). - Template text — the expanded code, with variables written as
$NAME$. - Context — where it's allowed to expand (Java statements, expressions, comments, etc.).
Two built-in variables deserve special mention. $END$ marks where the cursor lands after expansion finishes. $SELECTION$ wraps whatever code you had highlighted, which powers the "surround with" workflow — select a block, press Ctrl+Alt+T (Cmd+Alt+T on macOS), and wrap it in a try/catch or a null check.
A worked example: a logger template that fills in the class name
Open Settings → Editor → Live Templates. This works in both IntelliJ IDEA Community and Ultimate — no plugins required. Create a new template in the "Java" group (or your own group) with:
Abbreviation: logr
Template text:
private static final org.slf4j.Logger log =
org.slf4j.LoggerFactory.getLogger($CLASS_NAME$.class);
$END$Now click Edit variables and set the expression for CLASS_NAME to className(). That built-in function resolves to the enclosing class at expansion time, so you never type the class name yourself. Set the context to Java → Declaration so it only offers itself where a field is legal.
To verify: open any Java class, type logr at field level, press Tab. You should get the full logger declaration with the correct class name already substituted and the cursor at $END$. If nothing expands, the usual culprit is the context checkbox — a template scoped to "Statement" won't fire at class-body level.
Sharing templates across a team
Templates live in XML files, which makes them easy to distribute. From the Live Templates settings page you can export a group to a file, and a teammate can import it the same way. For ongoing sync, the Settings Repository feature (or simply committing the exported XML to your repo and re-importing on change) keeps everyone on the same abbreviations.
A practical tip: agree on a short prefix for team templates (e.g., tm-) so custom abbreviations don't collide with the dozens of built-ins like sout, psvm, and iter. Collisions don't break anything, but they do produce ambiguous completion popups that slow people down — the opposite of the goal.
Where Live Templates can bite you
Two limitations are worth knowing up front:
- Context-dependent variables can surprise you. Functions like
className()ormethodName()depend on where the cursor sits. In multi-module projects or unusual file layouts (generated sources, nested classes), the resolved value may not be what you expected. Always expand once in a real file before trusting a template in muscle memory. - Groovy-scripted variables add maintenance cost. You can attach arbitrary Groovy expressions to variables for dynamic content. Powerful, but heavy scripts are harder to read six months later and can add overhead. Prefer built-in functions; reach for scripts only when there's no built-in equivalent.
There's also a subtler risk: templates that generate too much code encourage copy-paste architecture. A template that scaffolds an entire service class is a sign the abstraction, not the typing, is the problem.
Start small, then standardize
The highest-value move isn't building fifty templates — it's identifying the three to five snippets your team types daily and templating exactly those. Check what you actually retype for a week (loggers, test method skeletons, builder stubs), create templates for them, export the group, and commit it next to your code style settings. Your future self, typing logr + Tab for the four-hundredth time, will thank you.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.