# Tempel: template expansion for Emacs that survived Tempo's long shadow

> Tempel is a small Emacs Lisp package that expands templates using the syntax of the ancient Tempo library, adding inline expansion and integration with completion-at-point-functions. It is one file, tempel.el, published on ELPA and MELPA, and it extends rather than replaces Tempo, which the author describes as an ancient temple of the church of Emacs that is over 32 years old and still in good shape.

**minad/tempel** — :classical_building: Tempel - Simple templates for Emacs

- Repository: https://github.com/minad/tempel
- Stars: 651 · Forks: 28
- Language: Emacs Lisp
- License: GPL-3.0
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/minad-tempel

## Why a successor to Tempo rather than a replacement

Tempel is described as a tiny template package for Emacs that uses the syntax of the Emacs Tempo library, and the framing of Tempo itself is the memorable part of the README: Tempo is an ancient temple of the church of Emacs, it is over 32 years old, but still in good shape since it successfully resisted change over the decades. However it looks a bit dusty here and there.

So Tempel is presented as the worthy successor, with inline expansion and integration with recent Emacs facilities. The key word is successor rather than replacement. Tempo remains, and Tempel speaks its template language, so a user moving over does not have to learn a new template syntax or rewrite their template files.

The one concrete piece of new machinery is that Tempel takes advantage of the standard completion-at-point-functions mechanism which is used by Emacs for in-buffer completion. That is the mechanism behind modern completion UIs such as Corfu, and hooking into it is what makes template expansion feel like part of the editor rather than a separate command you have to remember.

The package is Emacs Lisp, licensed GPL-3.0, and the repository is deliberately minimal. The top level holds .elpaignore, .github/, .gitignore, LICENSE, NEWS.org, README.org and tempel.el. One source file, one readme, a news file and a licence. The README itself is written in Org mode with the org-publish metadata at the top, which tells you that the documentation is expected to be read and republished in multiple formats.

The last push was on 2026-08-14, the project is not archived, and it publishes no GitHub releases, because the distribution channels are the package archives rather than this repository.

## Three commands, and they differ in how much they offer you

Tempel comes with three commands for template expansion, and the differences between them are about how much the completion UI shows you.

tempel-complete completes a template name at point in the buffer and subsequently expands the template. If called non-interactively the function behaves like a Capf and can be added to completion-at-point-functions, and the Capf returns a list of template names which are presented by the completion UI for selection.

tempel-expand expands an exactly matching template name at point in the buffer. It also behaves like a Capf when called non-interactively, but this Capf returns only the single exactly matching template name, such that no selection in the completion UI is possible.

tempel-insert selects a template by name via completing-read and inserts it into the current buffer.

So the choice is between seeing all the templates and expanding the one you typed, and one command that bypasses completion entirely. The practical difference shows up in a file with many templates: complete shows you a list, expand only fires when what you have typed is unambiguous, and insert asks by name.

The README suggests trying the author's Corfu completion at point popup UI for the complete and expand commands. After inserting the template you can move between the visible template fields with the keys M-{, M-} or C-up/down, which are normally bound to forward-paragraph and backward-paragraph. Tempel temporarily remaps these commands to tempel-next and tempel-previous, and if tempel-done-on-next is non-nil, as soon as you move before or behind the first or last field, the template is finished.

The key bindings are defined in the tempel-map keymap, and the README's advice is to inspect that keymap and look at the provided bindings, because they can be customised there.

## Configuration, and why the Capf is added before the programming mode one

The package is available on ELPA and MELPA and can be installed with package-install. The example configuration in the README relies on use-package, and the configuration file itself is the most instructive part of the documentation because it shows a subtlety.

The setup function adds the Tempel Capf to completion-at-point-functions, and the comment explains the ordering decision: tempel-expand only triggers on exact matches, and it is added before the main programming mode Capf such that it will be tried first.

```emacs-lisp
;; Configure Tempel
(use-package tempel
  :bind (("M-+" . tempel-complete) ;; Alternative tempel-expand
         ("M-*" . tempel-insert))

  :init

  ;; Setup completion at point
  (defun tempel-setup-capf ()
    ;; Add the Tempel Capf to `completion-at-point-functions'.  `tempel-expand'
    ;; only triggers on exact matches. We add `tempel-expand' *before* the main
    ;; programming mode Capf, such that it will be tried first.
    (setq-local completion-at-point-functions
                (cons #'tempel-expand completion-at-point-functions))
```

Because the Capf is set with setq-local, it is added per buffer, which is why the setup function is hooked into mode hooks rather than set globally. The configuration installs that hook for conf-mode-hook, prog-mode-hook and text-mode-hook, so a configuration file, a source file and a text file all get template expansion.

The commented-out block shows the alternative with a trigger prefix character, which prevents Tempel from triggering unexpectedly, using Corfu's own trigger machinery with tempel-complete rather than tempel-expand.

Two optional pieces follow. There is a commented pair of lines for making the Tempel templates available to Abbrev, either locally or globally, and then a use-package form for tempel-collection, the separate package of ready-made templates, which the README recommends checking out and asks people to contribute to. The last optional block enables the Corfu completion UI with global-corfu-mode.

## Templates are Lisp data, grouped by major mode

The template file format is worth understanding because it is where the actual work of using the package happens.

The templates are defined in a Lisp data file configured by tempel-path, and the templates are grouped by major mode with an optional :when condition. By default the file templates in the user-emacs-directory is used, for example ~/.config/emacs/templates. Each template is a list in the concise form of the Emacs Tempo syntax, where the first element of each list is the name of the template.

There is a naming recommendation that is easy to skip and easy to regret. Avoid special letters for the template names, since special letters may carry meaning during completion filtering and as such make it harder to select the desired template, so the name lett is better than let*. That is a small piece of advice with a clear mechanism behind it: the completion machinery treats certain characters specially, and a name like let* fights it.

Beyond the Tempo syntax elements, each template may specify several key/value pairs after the template elements. The :pre and :post keys take a FORM that is evaluated before the template is expanded or after it is finished respectively. The :post form is evaluated in the lexical scope of the template, which means that it can access the template's named fields, so a template can do something with the value you just typed when you leave the last field.

Templates may also include an :ann and a :doc key with strings used as annotation and documentation respectively. The :ann key is how a template leaves a comment behind in the buffer, and :doc is how a template carries its own documentation into the completion UI.

The README's examples section continues past what is reproduced here, and it is worth noting that the examples are written on a single line each, which suggests the intended density of a template definition.

## What to expect from a package this small

Tempel is one file, and that is simultaneously its appeal and its boundary.

The appeal is that you can read the whole implementation. There is no plugin layer, no configuration format beyond the Emacs Lisp you already write, and no dependency other than the Emacs Lisp libraries the package calls into. The template syntax is Tempo's, so the knowledge you need is the knowledge you either have from using Tempo or can pick up from the documentation, and there is a separate package of ready-made templates maintained by someone else for the templates you do not want to write.

The boundary is that the project is a convenience layer over a library that predates it by three decades. It does not replace Tempo, and it does not replace completion-at-point either; it plugs into the standard mechanism. The Corfu integration is optional and presented as a suggestion, and the Corfu popup UI is a separate project by the same author, so the package works without it but looks better with it.

The maintenance picture is small but current. The last push was on 2026-08-14, the repository is not archived, and the NEWS.org file in the root is the changelog. The distribution is through ELPA and MELPA, and the GNU-devel ELPA badge in the README shows it is also packaged in the development archive.

So the evaluation is straightforward. If you want inline template expansion in Emacs and you are comfortable with the Tempo syntax, this is a small, readable, currently maintained package that does one thing. If you want a broader snippet or scaffolding system, with LaTeX document generation or multiple snippet languages, this is deliberately not that, and tempel-collection or the surrounding Emacs ecosystem is where to look instead.

## Conclusion

Adopt Tempel if you want inline template expansion in Emacs and are comfortable with the Tempo template syntax, because the package is one readable source file that plugs into completion-at-point-functions rather than replacing the completion stack. Do not adopt it expecting a snippet or scaffolding system with LaTeX document generation or multiple snippet languages, since it is deliberately only a template expander. Before you commit, install it from ELPA or MELPA with package-install, add the Capf in the order the configuration example shows so tempel-expand is tried before the programming mode Capf, and name your templates without special characters so the completion filter can select them.

## FAQ

### What is Tempel and how does it relate to Emacs Tempo?

Tempel is a small Emacs Lisp template package that uses the syntax of the Tempo library, presenting itself as Tempo's worthy successor with inline expansion and completion-at-point integration. Tempo itself is described as over 32 years old and still in good shape, so Tempel extends rather than replaces it.

### What is the difference between tempel-complete, tempel-expand and tempel-insert?

tempel-complete completes a template name at point and then expands it, returning a list of names to the completion UI. tempel-expand expands an exactly matching template name only, so no selection is possible. tempel-insert selects a template by name through completing-read and inserts it.

### How do I install and configure Tempel in Emacs?

The package is on ELPA and MELPA and installs with package-install. The example configuration uses use-package, binds M-+ to tempel-complete and M-* to tempel-insert, and adds tempel-expand to completion-at-point-functions in a setq-local inside a setup function hooked into conf-mode-hook, prog-mode-hook and text-mode-hook, so the Capf is added before the main programming mode Capf.

### Where does Tempel look for template files and what format are they in?

The templates live in a Lisp data file configured by tempel-path, and by default the templates file in the user-emacs-directory is used, for example ~/.config/emacs/templates. Templates are grouped by major mode with an optional :when condition, and each one is a list in the concise form of the Tempo syntax whose first element is the template name.

## Sources

- [Issues](https://github.com/minad/tempel/issues)
- [License: GPL-3.0](https://github.com/minad/tempel/blob/main/LICENSE)
- [minad/tempel on GitHub](https://github.com/minad/tempel)
- [README](https://github.com/minad/tempel/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/minad-tempel
