VOMPECCC: A Modular Completion Framework for Emacs
Table of Contents
- 1. About emacs completion modularity
- 2. The Hidden Complexity of Completion complexity design
- 3. The Monolith Era: Helm and Ivy helm ivy legacy
- 4. The VOMPECCC Framework vompeccc framework
- 5. Vertico: The Display Layer vertico display
- 6. Orderless: The Filtering Layer orderless filtering
- 7. Marginalia: The Annotation Layer marginalia annotations
- 8. Prescient: The Sorting Layer prescient sorting
- 9. Embark: The Action Layer actions
- 10. Consult: The Command Layer consult commands
- 11. Corfu: The In-Buffer Display Layer corfu completion
- 12. Cape: The In-Buffer Backend Layer cape backends
- 13. The Subset Property: Use What You Want modularity flexibility
- 14. Growth and Adoption Timeline timeline adoption
- 15. The Trade-Off: Monolith vs. Composition tradeoffs analysis
- 16. Conclusion conclusion
- 17. TLDR tldr
1. About emacs completion modularity
Figure 1: JPEG produced with DALL-E 3
Completion is not a feature or UI, but instead it is a system composed of at least half a dozen orthogonal concerns that most users never think about separately. The previous post in this series argued that Emacs uniquely exposes completion as a programmable substrate rather than a sealed UI, and that this substrate is what makes Incremental Completing Read (ICR) viable as a primary interaction pattern in Emacs. This post is about the packages that build on that substrate in practice.
VOMPECCC is a loose acronym for eight of them that, together, form a complete, modular, Unix-philosophy-aligned completion framework for Emacs: Vertico, Orderless, Marginalia, Prescient, Embark, Consult, Corfu, and Cape. Each package does one thing, and the key attribute of all eight is that they compose through Emacs's standard completion APIs, meaning any subset works without the others.
I'm writing this post because these packages have recently taken the Emacs community by storm, but I rarely see discussions on how they relate or how they compose together to provide a feature complete ICR system in emacs. These packages implement concretely what the antecedent post argues in the abstract: completion is a substrate, or set of primitives, on top of which users can build rich interfaces for effortlessly interacting with your machine to do almost anything.
3. The Monolith Era: Helm and Ivy helm ivy legacy
For the better part of a decade, two incredible frameworks dominated Emacs completion: Helm and Ivy. Both were genuinely transformative, because in my opinion, they proved that Emacs's built-in completion experience was inadequate, and they inspired everything that followed. But both, in retrospect, made the same architectural trade-off: they bundled every concern into a single package with a single API. I have used both packages extensively, as both a package author and a consumer. The benefits were immediate for me, but the costs emerged over time.
3.1. Helm: The Kitchen Sink
Helm traces its lineage to anything.el, created by Tamas Patrovics in 2007. Thierry Volpiatto, a French alpine guide who taught himself programming after discovering Linux in 20061, forked it as Helm in 2011 and contributed nearly 7,000 commits over the following decade. Helm became the most downloaded package on MELPA2 and the default completion framework in Spacemacs, which drove massive adoption during 2013–2018.
Helm's ambition was impressive but all-encompassing. It provided its own candidate display, filtering, action system, source API (via EIEIO classes), and dozens of built-in commands for things like file finding, buffer switching, grep, and more…. The actions system was comprehensive too — it offered 44+ file actions alone.
Helm showed what great completion could feel like. Its architecture showed what happens when a single maintainer carries every concern alone.
The cost was proportional to Thierry's ambition. Users reported multi-second delays on basic operations after extended use, 100–500ms lag on window popups, and CPU-intensive fuzzy matching that required disabling for large projects. Samuel Barreto's widely cited "From Helm to Ivy" essay called Helm "a big behemoth size package" and reported using only a third of its capabilities.
Most critically, Helm replaced Emacs's completing-read entirely with its own proprietary helm-source API. Every Helm extension was written against this API. None of them could be reused with any other completion system. That was the helm killer for me: if Helm's development stalled — and it did, twice, in 2018 and 20203 — every downstream package would be stranded.
3.2. Ivy: The Lighter Monolith
Ivy emerged in 2015 as Oleh Krehel's direct reaction to Helm's complexity. Where Helm tried to do everything, Oleh aimed to be more minimalist or at least better factored. The package split its concerns into three logical components: Ivy (the completion UI), Swiper (an isearch replacement), and Counsel (enhanced commands).
In practice, the split was cosmetic. All three lived in a single repository. Counsel was coupled to Ivy's internals. And the core architectural choice was the same as Helm's: Ivy defined its own completion API, ivy-read, and Counsel commands called ivy-read directly rather than completing-read. Code written for Ivy worked only with Ivy.
The ivy-read function grew organically to accept roughly 20 arguments with multiple special cases4. As the Selectrum developers noted: "When Ivy became a more general-purpose interactive selection package, more and more special cases were added to make various commands work properly." Users reported performance degradation after extended use, and Ivy broke with Emacs 28 and again with Emacs 30, forcing compatibility polyfills. This is stressful for not only the consumers of Ivy, but also for the maintainers.
When Ivy's original maintainer stepped back, the project entered a period of reduced maintenance. A new maintainer has since taken over and released version 0.15.1, but active feature development has slowed considerably from the 2016–2020 peak.
3.3. The Unix Philosophy Lens
The Unix philosophy, as articulated by Doug McIlroy5, is straightforward: "Write programs that do one thing and do it well. Write programs to work together." Viewed through this lens, both Helm and Ivy bundle too many concerns into packages that communicate through proprietary APIs (helm-source, ivy-read) rather than Emacs's native completing-read contract. The result is that extensions and backends written for one framework cannot be reused with another, making an investment in either tool non-transferable.
None of this diminishes what they achieved, by the way. I'm personally a huge Helm and Ivy fan and I've build with them and consumed them directly for years. In my opinion, the legacy of Helm and Ivy is that they showed the community what great completion felt like, and gave a taste of what a fully featured completion system built on the Emacs substrate could be. The question is whether the architecture that delivered those features is the one we want to build on going forward.
The irony is that Emacs already provides the right abstraction.
completing-readis a stable, well-specified API that any UI can render6.completion-stylesis a pluggable system for controlling how input matches candidates7.completion-at-point-functionsis a standard hook for in-buffer completion backends.
The infrastructure for composable completion has existed for years. It just needed packages that actually used it.
4. The VOMPECCC Framework vompeccc framework
VOMPECCC is not a framework in the traditional sense. There is no single repository, no shared dependency, and no coordinating package. It is eight independent packages, maintained by three different developers, that compose through Emacs's standard APIs to cover every concern of a complete completion system.
| Package | Concern | Author |
|---|---|---|
| Vertico | Minibuffer display | Daniel Mendler |
| Orderless | Filtering / matching | Omar Antolin Camarena & Daniel Mendler |
| Marginalia | Candidate annotations | Omar Antolin Camarena & Daniel Mendler |
| Prescient | Sorting / ranking | Radon Rosborough |
| Embark | Contextual actions | Omar Antolin Camarena |
| Consult | Enhanced commands | Daniel Mendler |
| Corfu | In-buffer display | Daniel Mendler |
| Cape | In-buffer backends | Daniel Mendler |
The architecture maps cleanly onto the six concerns identified earlier:
Minibuffer Buffer
---------- ------
Display: Vertico Corfu
Filtering: Orderless (shared across both)
Sorting: Prescient (shared across both)
Annotations: Marginalia (shared across both)
Actions: Embark (shared across both)
Backends: Consult Cape
Each package targets a single layer, and they all communicate through standard Emacs APIs: completing-read, completion-styles, completion-at-point-functions, annotation functions, and keymaps. No package knows about the others' internals ‼️, and because of this all of them can be replaced without affecting the rest.
5. Vertico: The Display Layer vertico display
Vertico (VERTical Interactive COmpletion) provides a vertical candidate list in the minibuffer. It is roughly 600 lines of code, excluding its extensions.
Vertico's defining characteristic is strict adherence to the completing-read contract. It doesn't filter candidates (that's your completion style's job). It doesn't sort them (that's your sorting function's job). It doesn't annotate them (that's your annotation function's job). It just displays them. Any command that calls completing-read, whether built-in or third-party, automatically gets Vertico's UI with zero configuration.
If you think 1 package for display is overkill, like I originally did before migrating to VOMPECCC, keep reading.
Vertico ships with 13 built-in extensions that modify the display behavior:
| Extension | Effect |
|---|---|
vertico-buffer |
Display in a regular buffer instead of the minibuffer |
vertico-directory |
Ido-like directory navigation (backspace deletes path components) |
vertico-flat |
Horizontal, flat display |
vertico-grid |
Grid layout |
vertico-indexed |
Select candidates by numeric prefix argument |
vertico-mouse |
Mouse scrolling and selection |
vertico-multiform |
Per-command or per-category display configuration |
vertico-quick |
Avy-style quick selection keys |
vertico-repeat |
Repeat last completion session |
vertico-reverse |
Bottom-to-top display |
vertico-suspend |
Suspend and restore completion sessions |
vertico-unobtrusive |
Show only a single candidate |
The vertico-multiform extension is particularly worth configuring: it lets you set per-command display modes, so consult-line can open in a full buffer while M-x stays in the minibuffer.
Created: April 2021. Stars: ~1,800. Available on: GNU ELPA.
6. Orderless: The Filtering Layer orderless filtering
Orderless is a completion style — it plugs into Emacs's completion-styles variable, the standard mechanism for controlling how user input is matched against candidates. Where built-in styles like basic require prefix matching and flex does single-pattern fuzzy matching, Orderless splits your input into space-separated components and matches candidates that contain all components in any order (Orderless reveals its namesake 😜).
Each component can independently use a different matching method:
| Style | Example | Matches |
|---|---|---|
orderless-literal |
buffer |
switch-to-buffer |
orderless-regexp |
^con.*mode$ |
conf-mode |
orderless-initialism |
stb |
switch-to-buffer |
orderless-flex |
stbf |
switch-to-buffer |
orderless-prefixes |
s-t-b |
switch-to-buffer |
orderless-literal-prefix |
swi |
switch-to-buffer |
Style dispatchers let you select a matching method per component using affix characters: == for literal, ~ for flex, , for initialism, ! for negation, & to match annotations. The system is fully extensible.
The typical configuration sets completion-styles to '(orderless basic), with partial-completion for the file category so that ~/d/s expands path components like ~/Documents/src. The fallback to basic is deliberate: some Emacs features (TRAMP hostname completion, dynamic completion tables) require a prefix-matching style.
Let's keep beating the dead horse of this post's theme: because Orderless is a standard completion style, it works with any completion UI that uses Emacs's completing-read API: Vertico, Icomplete, the default *Completions* buffer, and even the minibuffer in Emacs's stock configuration.
Quick timeout: for readers getting to this point thinking "Wow Vertico plus Orderless is a power stack, let's keep stacking", you certainly can see things this way, but instead, I encourage you to consider what it would be like to use each package without the others. That will give you a better understanding of how the consituent stars in the VOMPECCC constellation behave independently. And that's the long term ROI you'll get from VOMPECCC. The independence is what makes stacking safe and fortuitous, but it doesn't make it necessary.
Created: April 2020. Stars: ~979. Available on: GNU ELPA.
7. Marginalia: The Annotation Layer marginalia annotations
Marginalia adds contextual annotations to minibuffer completion candidates. The name refers to notes written in the margins of books, and here it means metadata displayed alongside each candidate.
Marginalia detects the category of the current completion (files, commands, variables, faces, buffers, bookmarks, packages, etc.) and selects an appropriate annotator function. The detection works through two mechanisms: marginalia-classify-by-command-name (lookup table keyed by calling command) and marginalia-classify-by-prompt (regex matching against the minibuffer prompt text).
| Category | Annotations shown |
|---|---|
| Command | Keybinding, docstring summary |
| File | Size, modification date, permissions |
| Variable | Current value, docstring |
| Face | Preview of the face styling |
| Symbol | Class indicator (v/f/c), docstring |
| Buffer | Mode, size, file path |
| Bookmark | Type, target location |
| Package | Version, status, description |
marginalia-cycle (typically bound to M-A) lets you cycle between annotation levels: detailed, abbreviated, or disabled entirely. This is useful when annotations are consuming screen space during narrow completions.
Marginalia hooks into Emacs's annotation-function and affixation-function properties in completion metadata. Sorry again to the dead horse I've been wailing on, but yes, this means Marginalia works with any completion UI that respects these properties. It is the framework-agnostic successor to ivy-rich8, which provided similar annotations but was Ivy-specific. It's cool to see Oleh and Thierry's visions carry on in these packages!
This was a mind blower to me when I discovered it - one subtle but consequential effect of using Marginalia is that the annotations themselves become searchable. Combined with Orderless's & style dispatcher, your input can match against annotation text as well as candidate names: running M-x and typing window &frame narrows to commands whose name contains "window" and whose docstring contains "frame". The search/matching space extends beyond candidate identifiers into candidate metadata, which is an unusually large leverage gain for what feels like a cosmetic layer. You are no longer constrained to remembering exact names (🤯); you can reach for commands, files, or buffers by properties that were previously invisible to your completion input. This helps to solve for cases where you have a ICR UI, but you don't know exactly what you're looking for. It can also be used to help you 'browse' candidates based on their characteristics as opposed to their names. Honestly my favorite feature of any of the VOMPECCC packages.
Created: December 2020. Stars: ~919. Available on: GNU ELPA.
8. Prescient: The Sorting Layer prescient sorting
Prescient provides intelligent sorting and filtering of completion candidates based on recency and frequency of use. The portmanteau frecency captures the combined metric that drives the ranking.
Orderless and Prescient are often confused with one another: the difference is that while Orderless answers "which candidates match?", Prescient answers "in what order should they appear?"
The sorting is hierarchical:
- Recency — most recently selected candidates appear first
- Frequency — frequently selected candidates next, with scores that decay over time
- Length — remaining candidates sorted by string length (shorter first)
Usage statistics persist across Emacs sessions via prescient-persist-mode, which writes to a save file. This means Prescient learns your habits: if you frequently run magit-status from M-x, it surfaces near the top after a few uses, regardless of where it falls alphabetically.
Prescient ships as a core library plus framework-specific adapters — vertico-prescient and corfu-prescient being the relevant ones for VOMPECCC. A key architectural insight is that both Vertico and Corfu work seamlessly with Prescient.
A common and powerful configuration combines Orderless for filtering with Prescient for sorting. Among the candidates filtered by Orderless, the most recent and frequent ones get promoted to the top.
Prescient also provides its own filtering methods (literal, regexp, initialism, fuzzy, prefix, anchored) with on-the-fly toggling via M-s prefix commands. However, I personally prefer Orderless for filtering and use Prescient purely for its sorting intelligence. I sort of act as if Prescient was cohesive in this way, rather than giving it responsibility for 2 orthogonal features.
Created: August 2017. Stars: ~695. Available on: MELPA.
9. Embark: The Action Layer actions
Embark provides a framework for performing context-aware actions on "targets" — the thing at point or the current completion candidate. Think of it as a keyboard-driven right-click context menu that works everywhere in Emacs: in the minibuffer and in normal buffers.
The core command is embark-act. When invoked, Embark determines the type of the target (file, buffer, URL, symbol, command, etc.) and opens a keymap of single-letter actions appropriate to that type:
| Target | Example actions |
|---|---|
| File | Open, delete, copy, rename, byte-compile, open as root |
| Buffer | Switch to, kill, bury, open in other window |
| URL | Browse, download, copy |
| Symbol | Describe, find definition, find references |
| Package | Install, delete, describe, browse homepage |
There are over 100 preconfigured actions across all target types.
Beyond embark-act, Embark provides several other capabilities:
embark-dwimruns the default action without showing the menuembark-act-allapplies the same action to every current candidate (e.g., kill all matching buffers)embark-collectsnapshots current candidates into a persistent bufferembark-livecreates a live-updating collection that refreshes as you typeembark-exportexports candidates into the appropriate Emacs major mode: file candidates become a Dired buffer, grep results become a grep-mode buffer (editable withwgrep), buffer candidates become an Ibuffer bufferembark-becomeswitches to a different command mid-stream, transferring your input
Two of these deserve special attention, because they change what a completion session is.
embark-collect freezes the current candidate set into a standalone buffer that persists after the minibuffer exits. This converts an ephemeral interaction (browse, pick, leave) into something durable (collect, hand off, revisit later). The collected buffer remains an Embark target, so the same keymap of actions applies to each entry. It is the right tool when the candidate list itself is the useful artifact: a shortlist of files to process, a set of buffers you want to act on later, a reference you want to keep open on the side.
embark-export goes one step further: instead of a generic candidate buffer, it materializes a buffer in the native major mode appropriate to the candidate type. File candidates become a Dired buffer, with Dired's decades of filesystem operations available. Grep-style candidates become a grep-mode buffer that wgrep can turn into a multi-file editing session, buffer candidates become Ibuffer, package candidates become the package menu, etc…. Each export targets a major mode purpose-built for the candidate type, so you end up inside the tool that was already the best one for the job, arrived at on demand, from a completion prompt, with no navigation overhead. Few interaction patterns in computing convert generic into specialized this cleanly.
Embark is a difference of kind, not quantity, compared to Helm and Ivy's action systems — because it works everywhere, across all types of objects9.
Using embark and consult together we can see a canonical example of this pattern: exporting consult-ripgrep results gives you a wgrep-editable grep buffer, so the workflow — search with Consult, export with Embark, edit with wgrep — compounds three independent packages into a multi-file refactor tool without any of them knowing about the others.
Created: May 2020. Stars: ~1,200. Available on: GNU ELPA.
10. Consult: The Command Layer consult commands
Consult provides 50+ enhanced commands built on completing-read. It is the spiritual successor to Counsel (from the Ivy ecosystem) but designed to work with any completion UI. Where Counsel called ivy-read directly, Consult uses the native contract, which means its commands work with Vertico, Icomplete, fido-mode, or even Emacs's default completion buffer.
Consult's commands span several categories:
Search:
| Command | Purpose | Replaces |
|---|---|---|
consult-line |
Search lines in current buffer | Swiper |
consult-line-multi |
Search across multiple buffers | Swiper-all |
consult-ripgrep |
Async ripgrep search | counsel-rg |
consult-grep |
Async grep search | counsel-grep |
consult-git-grep |
Git-aware grep | counsel-git-grep |
consult-find |
Async file finding | counsel-find |
Navigation:
| Command | Purpose | Replaces |
|---|---|---|
consult-buffer |
Enhanced buffer switching | helm-mini |
consult-imenu |
Flat imenu with grouping | helm-imenu |
consult-outline |
Navigate headings with preview | Built-in |
consult-goto-line |
Goto line with live preview | Built-in |
consult-bookmark |
Enhanced bookmark selection | Built-in |
consult-recent-file |
Recent file selection with preview | counsel-recentf |
Editing and miscellaneous:
| Command | Purpose |
|---|---|
consult-yank-from-kill-ring |
Browse kill ring interactively |
consult-theme |
Preview themes before applying |
consult-man |
Async man page lookup |
consult-flymake |
Navigate Flymake diagnostics |
consult-org-heading |
Navigate org headings |
Three features make Consult particularly powerful:
Live preview: Most commands show a real-time preview as you navigate candidates. consult-line highlights the matching line in the buffer. consult-theme applies the theme before you select it. consult-goto-line scrolls to the line as you type the number.
Narrowing and grouping: consult-buffer combines buffers, recent files, bookmarks, and project items into a single unified list. Narrowing keys filter to a single source: b SPC for buffers, f SPC for files, m SPC for bookmarks. Custom sources can be added via consult-buffer-sources.
Two-level async filtering: Commands like consult-ripgrep split input at #: everything before it goes to the external tool as the search pattern, everything after it filters the results locally with your completion style. error#handler searches for "error" with ripgrep, then narrows to results containing "handler" using Orderless. Async support is an enormously important feature, because it makes the cognitive cost of search roughly constant with respect to the size of the search space.
Created: November 2020. Stars: ~1,600. Available on: GNU ELPA.
11. Corfu: The In-Buffer Display Layer corfu completion
Corfu (COmpletion in Region FUnction) is simply the in-buffer counterpart to Vertico. Where Vertico handles minibuffer completion display, Corfu handles the popup that appears at point when you complete a symbol while writing code or text. It is roughly 1,220 lines of code.
Corfu's defining architectural choice mirrors Vertico's: it hooks into Emacs's built-in completion-in-region mechanism rather than inventing its own backend system. Any mode that provides a completion-at-point-function (Eglot, Tree-sitter, elisp-mode, etc.) works with Corfu automatically. Any completion-style (basic, partial-completion, orderless) can be used for filtering.
This is the fundamental difference from Company, the incumbent in-buffer completion framework10. Company uses its own proprietary company-backends API. Company backends don't work with completion-at-point, and Capfs don't work with Company (without an adapter). Anecdotally, I've had many wrestling matches with Company and always found it incredibly difficult to set up properly. Corfu eliminates this split. Doom Emacs recognized this: Company is now deprecated in Doom in favor of Corfu, with plans to remove it post-v311.
| Aspect | Company | Corfu |
|---|---|---|
| Backend system | Proprietary | Emacs-native Capfs |
| Popup technology | Overlays | Child frames |
| Completion styles | Limited | Any Emacs style |
| Codebase size | Many files, 3,900+ LOC in main file | Single file, ~1,220 LOC |
| Created | 2009 | 2021 |
Corfu ships with seven built-in extensions:
| Extension | Purpose |
|---|---|
corfu-echo |
Brief candidate documentation in the echo area |
corfu-history |
Sort by selection history/frequency |
corfu-indexed |
Select candidates by numeric prefix argument |
corfu-info |
Access candidate location and documentation |
corfu-popupinfo |
Documentation popup adjacent to the completion menu |
corfu-quick |
Avy-style quick key selection |
Created: April 2021. Stars: ~1,400. Available on: GNU ELPA.
12. Cape: The In-Buffer Backend Layer cape backends
Cape (Completion At Point Extensions) provides a collection of modular completion backends (Capfs) and a powerful set of Capf transformers for composing and adapting them. If Corfu is the frontend (how completions are displayed), Cape is the backend toolkit (what completions are available).
Cape provides 13 completion backends, here are some highlights:
| Capf | Purpose |
|---|---|
cape-dabbrev |
Dynamic abbreviation from current buffers |
cape-file |
File path completion |
cape-elisp-block |
Elisp completion inside Org/Markdown blocks |
cape-keyword |
Programming language keyword completion |
cape-history |
History completion in Eshell/Comint |
The remaining backends cover dictionary words, emoji, abbreviations, line completion, and Unicode input via TeX, SGML, and RFC 1345 mnemonics.
Cape's Capf transformers are higher-order functions that wrap and modify backends:
cape-capf-supermerges multiple Capfs into a single unified sourcecape-capf-case-foldadds case-insensitive matchingcape-capf-inside-code/cape-capf-inside-string/cape-capf-inside-commentrestrict activation to specific syntactic regionscape-capf-prefix-lengthrequires a minimum prefix before activatingcape-capf-predicatefilters candidates with a custom predicatecape-capf-sortapplies custom sorting
The cape-company-to-capf adapter converts any Company backend into a standard Capf, without requiring Company to be installed. This bridges the two ecosystems: you can use Company-era backends (like company-yasnippet) with Corfu. I don't personally do this, but you can if you want!
Created: November 2021. Stars: ~760. Available on: GNU ELPA.
13. The Subset Property: Use What You Want modularity flexibility
The most important property of VOMPECCC is that you don't need to buy into all eight packages. You can start with one, add another when you feel a gap, and swap any component for an alternative without breaking anything else.
If you're into inverting dependencies, VOMPECCC is your bag, man.
This works because every package communicates through the native Emacs APIs rather than depending on each other's internals. There are no hard dependencies between any of the eight packages. Here is a map of what each package can be replaced with — or simply omitted:
| Package | Alternative | Or simply… |
|---|---|---|
| Vertico | Icomplete-vertical, Mct, Ido, fido-mode | Default *Completions* buffer |
| Orderless | Hotfuzz, Fussy, Prescient (filtering mode) | Built-in flex or substring |
| Marginalia | (none equivalent) | No annotations (still works) |
| Prescient | savehist-mode + vertico-sort-override |
Alphabetical sorting |
| Embark | (none equivalent) | Direct command invocation |
| Consult | Built-in switch-to-buffer, grep, etc. |
Standard Emacs commands |
| Corfu | Company, completion-preview-mode |
Default *Completions* buffer |
| Cape | Company backends, hippie-expand |
Mode-provided Capfs |
Some practical subset configurations:
Minimal (2 packages): Vertico + Orderless. You get a vertical candidate list with multi-component matching. No annotations, no actions, no enhanced commands — but a dramatically better M-x and find-file experience than stock Emacs.
Comfortable (4 packages): Vertico + Orderless + Marginalia + Consult. Now you have annotations on every candidate and enhanced commands with live preview. This is probably the sweet spot for most users.
Full stack (8 packages): All of VOMPECCC. Complete coverage of both minibuffer and in-buffer completion, with intelligent sorting, contextual actions, and modular backends.
For concrete configuration, the most reliable starting point is each package's own repository — every package linked in the opener ships a comprehensive README with example use-package snippets, and most also provide wikis or info manuals covering more specialized use cases (Vertico's per-command vertico-multiform patterns, Cape's Capf transformer recipes, Embark's keymap customization examples, Consult's custom sources, and so on). Reading those directly is faster than copying a consolidated configuration and then reverse-engineering what each line does, and it scales better as the packages themselves evolve.
14. Growth and Adoption Timeline timeline adoption
The history of Emacs completion frameworks is a progression from monolithic solutions toward composable ones.
| Year | Event |
|---|---|
| 1996 | Kim F. Storm begins Ido |
| 2007 | Ido included in Emacs 22; anything.el created (Helm's ancestor) |
| 2011 | Volpiatto forks anything.el as Helm |
| 2013–2018 | Helm's golden era: most-downloaded MELPA package, default in Spacemacs |
| 2015 | Krehel creates Ivy/Swiper/Counsel |
| 2016 | "From Helm to Ivy" blog post sparks migration; Ivy peaks ~2016–2020 |
| 2017 | Rosborough creates Prescient |
| 2018 | Helm enters bug-fix-only mode (maintainer burnout) |
| 2019 | Rosborough creates Selectrum (first completing-read-native UI) |
| 2020 Apr | Antolin Camarena creates Orderless |
| 2020 May | Antolin Camarena creates Embark |
| 2020 Sep | Helm development officially stopped |
| 2020 Nov | Mendler creates Consult |
| 2020 Dec | Antolin Camarena & Mendler create Marginalia |
| 2021 Apr | Mendler creates Vertico and Corfu |
| 2021 May | "Replacing Ivy and Counsel with Vertico and Consult" (System Crafters) |
| 2021 | Selectrum deprecated in favor of Vertico; Doom Emacs adds Vertico module |
| 2021 Nov | Mendler creates Cape |
| 2022 | Doom Emacs switches default completion from Ivy to Vertico |
| 2024 | Ivy breaks with Emacs 30; Company deprecated in Doom in favor of Corfu |
Helm and Ivy accumulated stars over a longer period; the newer packages are growing faster relative to their age (counts as of early 2026):
| Package | Stars | Created | Approx. age |
|---|---|---|---|
| Helm | ~3,500 | 2011 | 15 years |
| Ivy/Swiper | ~2,400 | 2015 | 11 years |
| Vertico | ~1,800 | April 2021 | 5 years |
| Consult | ~1,600 | Nov 2020 | 5 years |
| Corfu | ~1,400 | April 2021 | 5 years |
| Embark | ~1,200 | May 2020 | 6 years |
| Orderless | ~979 | April 2020 | 6 years |
| Marginalia | ~919 | Dec 2020 | 5 years |
| Cape | ~760 | Nov 2021 | 4 years |
| Prescient | ~695 | Aug 2017 | 9 years |
The community momentum is clear. Doom Emacs, one of the most popular Emacs distributions, has moved to Vertico + Corfu as its defaults12. Modern configuration guides almost universally recommend the modular stack13. And the upstream Emacs project itself has been integrating ideas from this ecosystem: Emacs 30 added completion-preview-mode, and Emacs 31 is incorporating Mct-inspired features (they love Prot, and for good reason, lol).
15. The Trade-Off: Monolith vs. Composition tradeoffs analysis
Engineering is about trade-offs. The modular approach has real advantages, but it does have costs, so I want to be honest about them:
15.1. Advantages of VOMPECCC
No vendor lock-in. Every package builds on the same native contracts. If any one of the eight packages is abandoned, you replace it. Your other packages continue to work. Contrast this with Helm, where the maintainer's burnout announcement stranded an entire ecosystem of downstream packages.
Independent maintenance. Three different developers maintain the eight packages. Daniel Mendler maintains five (Vertico, Consult, Corfu, Cape, and co-maintains Marginalia), so the overall bus factor is not dramatically higher than a monolith. But the key difference is structural: if Mendler stepped away, the remaining packages would continue to function independently. Omar Antolin Camarena's Embark and Orderless would keep working. Radon Rosborough's Prescient would keep working. Nobody's contribution is stranded by someone else's absence.
Incremental adoption. You start with one package and add more as you discover needs. There is no cliff of initial configuration. You never need to understand all eight before getting value from any one.
Smaller, auditable codebases. Vertico is ~600 lines. Corfu is ~1,220 lines. These are packages you can actually read end to end. Bugs are easier to find and fix in small, focused codebases.
Automatic ecosystem benefits. Because everything uses the native completion protocol, third-party packages benefit for free. Any command that calls completing-read gets your chosen UI, filtering, sorting, annotations, and actions without any integration code.
Future compatibility. Emacs itself continues to improve its built-in completion system. Packages built on the native protocol benefit from those improvements automatically. Packages built on proprietary APIs do not.
15.2. Disadvantages of VOMPECCC
Higher initial discovery cost. A newcomer searching "Emacs completion" finds eight packages instead of one. Understanding the role of each, and which subset to start with, requires more research than "install Helm" or "install Ivy." The conceptual overhead is non-trivial.
Configuration across packages. Eight packages means eight use-package declarations, eight sets of configuration variables, and eight places where something could be misconfigured. Helm's all-in-one approach means one declaration, one set of variables, one source of truth.
Interaction effects. While the packages are independent, some combinations require awareness of how they interact. Combining Orderless with Prescient requires understanding that Orderless handles filtering while Prescient handles sorting. The embark-consult integration package exists because the two packages benefit from knowing about each other in specific workflows.
Less out-of-the-box polish. Helm ships with dozens of purpose-built commands. With VOMPECCC, you compose those workflows yourself. The result is often more powerful, but you build it rather than unwrap it.
Documentation is distributed. Each package has its own README, its own issue tracker, its own wiki. There is no single "VOMPECCC manual." Cross-cutting workflows (search with Consult, export with Embark, edit with wgrep) are documented across multiple repositories.
15.3. When to Choose What
Choose VOMPECCC if:
- You value understanding your tools and want to read the source code
- You want completion that works identically with built-in and third-party commands
- You want to invest incrementally rather than all at once
- You care about long-term maintainability and Emacs version compatibility
- You want to mix and match components as your needs evolve
Consider Helm if:
- You want maximum out-of-the-box functionality with minimal configuration
- You prefer a single point of documentation and support
- You are comfortable depending on a single package and its API
- You need one of Helm's highly specific, purpose-built features (like
helm-toporhelm-colors) and don't want to replicate them - You think Thierry is a cool dude (he is)
Consider Ivy if:
- You are already invested in the Ivy ecosystem with custom
ivy-readcode - You prefer Ivy's action selection UX
- You need Spacemacs's Ivy layer specifically
- You think Oleh is a cool dude (he is)
For new configurations today, the community consensus points strongly toward the modular stack. Doom Emacs's switch to Vertico and Corfu, the deprecation of Selectrum, and the ongoing maintenance challenges of both Helm and Ivy have made the direction clear. The question is no longer whether to use the modular approach, but which subset to start with.
16. Conclusion conclusion
I came to this stack the way most people probably do: one package at a time, over the course of a year or so. I started with Vertico and Orderless because my Ivy config had started fighting with Emacs 28 upgrades and I was tired of debugging someone else's ivy-read edge cases. Two packages, ten minutes of configuration, and M-x already felt better. Marginalia came next for me. Once you've seen keybindings and docstrings next to every command, you can't unsee their absence. Consult replaced Counsel, Embark replaced the "type search string, exit completion, run a different command" waltz, and Corfu replaced Company when I realized the same Orderless filtering I'd grown to depend on in the minibuffer wasn't available in my code buffers.
The whole migration happened very incrementally, which was incidental for me, but is the point of this post. I never sat down to "install VOMPECCC." I solved one friction at a time, and each solution composed with the ones I already had. That's the experience the architecture is designed to produce.
Nobody really calls it VOMPECCC in Emacs circles, it is a mnemonic used here for the sake of an article rather than an established term. But the packages it describes have quietly become the default recommendation for modern Emacs completion, adopted by Doom Emacs, recommended by Protesilaos Stavrou14, documented by System Crafters15, and built on by a growing ecosystem of third-party packages.
The shift from Helm to Ivy to the modular stack follows a familiar pattern in software: monoliths are convenient until they aren't. Composable tools with clear interfaces outlast the frameworks that try to be everything16. Emacs figured this out forty years ago, and the modular stack described here is what completion looks like once you treat it as a substrate, the raw material on top of which you build Incremental Completing Read interactions, rather than as a finished product the vendor hands you. Its completion ecosystem just needed a few years to catch up.
17. TLDR tldr
Emacs completion is not one problem but at least six orthogonal concerns: display, filtering, sorting, annotation, actions, and in-buffer completion. For a decade, Helm and Ivy delivered excellent experiences but bundled everything behind proprietary APIs, creating vendor lock-in and maintenance fragility. VOMPECCC names eight independent packages — Vertico, Orderless, Marginalia, Prescient, Embark, Consult, Corfu, and Cape — that each address a single concern and compose through Emacs's native completing-read contract rather than custom APIs. Because no package depends on another's internals, any subset works on its own and any component can be replaced without breaking the rest. The community has moved decisively toward this modular stack, with Doom Emacs switching its defaults to Vertico and Corfu. There are real trade-offs — higher discovery cost and distributed configuration — but the architecture pays off in durability, auditability, and incremental adoption.
Footnotes:
Sacha Chua's interview with Thierry Volpiatto (2018) provides a candid account of Helm's history. Volpiatto describes being a mountain guide with no programming background, discovering Linux in 2006, and gradually becoming Helm's sole maintainer. He also discusses the financial unsustainability of maintaining a package used by hundreds of thousands of users as a volunteer.
Helm accumulated over 640,000 downloads on MELPA, making it the most downloaded package on the archive at its peak. MELPA download counts are visible on the MELPA package page. The figure is cumulative since MELPA began tracking downloads in 2013.
Volpiatto's 2020 announcement (GitHub Issue #2386) was definitive: "Helm development is now stopped, please don't send bug reports or feature request, you will have no answers." The issue was locked to collaborators. The Hacker News discussion that followed highlights the difficulty of sustaining large open-source projects without institutional support.
The ivy-read signature can be inspected in ivy.el on GitHub. The Selectrum README (radian-software/selectrum) provides a detailed comparison of ivy-read with completing-read and explains why the deviation from the standard API created long-term maintainability problems.
McIlroy's articulation of the Unix philosophy appears in the Bell System Technical Journal's 1978 special issue on Unix (available at archive.org). The full quote is: "Make each program do one thing well. To do a new job, build afresh rather than complicate old programs by adding new 'features'." See also Eric S. Raymond's The Art of Unix Programming, Chapter 1, which elaborates on the philosophy's implications for software design.
The completing-read API is documented in the Emacs Lisp Reference Manual. The key design insight is that completing-read supports programmatic completion tables — functions that can compute candidates lazily based on the current input — which is essential for large or dynamic candidate sets like TRAMP hosts or LSP symbols.
Emacs's completion styles system is documented in the GNU Emacs Manual. The variable completion-styles controls which matching strategies are tried, in order, until one produces results. The completion-category-overrides variable allows per-category customization, so file completion can use partial-completion while M-x uses orderless.
ivy-rich (Yevgnen/ivy-rich) was a popular Ivy extension that added columns of information to Ivy completion candidates — essentially the same concept as Marginalia. The key limitation was that it was structurally coupled to Ivy: if you switched away from Ivy, you lost your annotations. Marginalia solves the same problem through the standard annotation-function API, making it framework-agnostic.
This characterization comes from Karthinks's "Fifteen Ways to Use Embark", one of the most comprehensive third-party guides to the package. The post demonstrates workflows that were impossible or impractical before Embark: acting on multiple candidates simultaneously, exporting completion results into native Emacs modes, and switching commands mid-stream without losing context.
Company-mode (company-mode/company-mode) was created by Nikolaj Schumacher in 2009 and has been maintained by Dmitry Gutov since 2013. It remains actively maintained with ~2,300 GitHub stars. The architectural critique here is specific to the backend API: company-backends is a separate protocol from completion-at-point-functions, which means backends written for Company don't work with other completion UIs, and vice versa.
The Doom Emacs Corfu module was merged in PR #7002 in March 2024. The Discourse discussion explains the rationale: Corfu aligns with Emacs's native completion infrastructure, while Company's proprietary API creates friction with the rest of the modern completion stack.
Doom Emacs's completion modules are documented at docs.doomemacs.org. The Vertico module includes pre-configured integration with Orderless, Marginalia, Consult, and Embark. The older Ivy and Helm modules remain available but are no longer the recommended default.
Notable guides recommending the modular stack include: Martin Fowler's "Improving my Emacs experience with completion" (2024), which documents his switch to the Vertico ecosystem; the "Guide to Modern Emacs Completion" by Jonathan Neidel, which walks through the full Vertico/Corfu stack; and Kristoffer Balintona's multi-part "Vertico, Marginalia, All-the-icons-completion, and Orderless" series (2022).
Protesilaos Stavrou's "Emacs: modern minibuffer packages (Vertico, Consult, etc.)" is a ~44 minute video demonstrating the full stack. Stavrou is also the author of Mct (Minibuffer and Completions in Tandem), an alternative approach that reuses the built-in *Completions* buffer with automatic updates. His recommendation of Vertico despite having written a competing package speaks to the strength of the ecosystem.
System Crafters' "Streamline Your Emacs Completions with Vertico" and the companion video "Replacing Ivy and Counsel with Vertico and Consult" (May 2021) were early catalysts for community adoption. David Wilson (System Crafters) documented his own migration from Ivy and provided configuration examples that became widely copied.
The pattern of monoliths giving way to composable architectures is well-documented in software engineering. Fred Brooks described the "second system effect" in The Mythical Man-Month (1975), where the follow-up to a successful lean system tends to be an overdesigned monolith. More recently, the microservices movement explicitly applies the Unix philosophy to distributed systems — with similar trade-offs around discovery cost, operational complexity, and distributed debugging.