# dumb-jump added a whole new jump backend and shipped it as a patch number

> dumb-jump is an Emacs jump-to-definition package for sixty-one languages that keeps no index and starts no background process, running a live search instead. The xref backend that most of its usage documentation describes arrived in 0.5.4, and the tag after that, 0.5.5, landed in February 2026.

**jacktasia/dumb-jump** — an Emacs "jump to definition" package for 60+ languages

- Repository: https://github.com/jacktasia/dumb-jump
- Stars: 1,800 · Forks: 163
- Language: Emacs Lisp
- License: GPL-3.0
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/jacktasia-dumb-jump

## A new backend shipped between two patch numbers four years apart

The tag history explains more about this package than its feature list does. v0.5.3 was cut in September 2019. v0.5.4 came in October 2021. v0.5.5 came in February 2026, and nothing has been tagged since, though commits continued to June 2026.

So the gap between 0.5.4 and 0.5.5 is a little over four years, and 0.5.4 is described in the usage section as the release that introduced the xref backend. A second selector system, a new key binding scheme, a new customization path and a new optional dependency all arrived in a patch-level increment on a project that had not left the 0.5 line since 2019.

The version floor documentation is tied to that same line. The package requires Emacs 26.1 or newer, and separately 0.5.5 is named as the last release supporting anything older. Those two statements are consistent but the combination is awkward: if you are on Emacs 25 there is no current tag for you, and 0.5.5 predates every feature the usage section teaches.

Six new tagged languages would be a bigger news item than this one got. What changed in 0.5.5 is not stated anywhere in the visible text.

## The example config contains paths the documented searcher cannot reach

Here is the example ignore file, indented the way the documentation shows it:

```
    -tests
    -node_modules
    -build
    -images
    +../some-lib/src
    +/usr/lib/src
```

The last two entries add paths outside the project, a sibling source tree and a system library tree. A minus removes a directory from the search, a plus adds one back.

Immediately below that example comes the warning: when adding paths outside the project with a plus sign, you must be using a searcher that can search outside the project root, and git-grep cannot do that. If you have forced the searcher to git-grep through either of the two settings that pin it, the plus entries silently do not work, so you should switch to ag or rg.

So the example the documentation hands you is not usable under one of the searchers the documentation also describes. The default automatic selection does not include git-grep, which limits the damage, but anyone who pinned it for speed gets a config that appears to include a sibling library and does not.

## A Makefile or a Cargo.toml can hijack the project root

The package looks for a project root so it knows where to search from. Thirteen markers qualify, and the list is worth reading closely:

```
.dumbjump  .projectile  .git  .hg  .fslckout  .bzr  _darcs  .svn  Makefile  PkgInfo  -pkg.el  _FOSSIL_  Cargo.toml
```

Eight of those are version control directories, which behave the way you would expect. The other five are build and package manifests. Any directory containing a Makefile or a Cargo.toml is treated as a project root, which means a nested subdirectory with its own build manifest can become the root, and searches will be scoped to that subdirectory instead of the repository.

There is an escape hatch, and it is a file rather than a setting. Drop an empty .dumbjumpignore in a directory and it stops registering as a project root, and the search continues looking upward.

This is the cost of a heuristic that needs no configuration. A monorepo with a Makefile per package, which is common in C projects, will land on whichever directory the search finds first, and there is no documented way to pin the root to the repository other than creating a .dumbjump file by hand.

## The stated minimum Emacs version does not give you the documented selection UI

The package requires Emacs 26.1. The recommended way to use it, however, is through the xref backend, activated by evaluating one line:

```elisp
(add-hook 'xref-backend-functions #'dumb-jump-xref-activate)
```

Once that is in place, xref decides how to present candidates, and the documentation then tells you to point it at a completing-read function so your own completion framework is used instead of the default pop-up buffer. That function has its own floor: it requires Xref 1.1.0, which is either downloaded from ELPA or bundled with Emacs 28.1 or newer.

So the chain of requirements is: Emacs 26.1 for the package, a recent-enough Xref for the customization, and Emacs 28.1 or an ELPA install to get both without extra work. Someone on 26.1 or 27 has a working jump command with the default pop-up and no completion framework, and the documentation does not call that case out separately.

Consult users set the same variable to consult-xref instead, which gives live preview of candidates as they cycle. Both paths are set through the same one variable, so the choice is entirely in your configuration.

## Two selector paths exist and the default depends on which one you took

When the package finds several candidates and cannot decide between them, it shows you a list. Which list depends on the path you are on.

The older path presents the choice through completing-read, which means Helm, Ivy, Icomplete or whatever else you have configured, routed through the dumb-jump-selector function. The newer xref path presents the choice in an xref buffer, and the documentation handles it separately further down the page.

The word legacy in that sentence is doing real work. The README describes the ambiguity case as applying only when you are on the legacy selector path, which implies the xref path handles the same ambiguity differently, and the details of how are in a section the reader is sent to rather than shown.

Find references is described as the inverse operation and works differently underneath. Instead of looking for where something is defined, it does a broad search for where a symbol is used and then filters out anything matching a definition pattern. Because it needs no new pattern set per language, it is stated to work for all the supported languages with no extra configuration.

That asymmetry is the design: definitions need a per-language rule table, usages do not.

## No index means your speed is your grep

The stated design goal is that the package just works, which is spelled out as minimal and ideally zero configuration with no stored indexes and no persistent background processes. There is no TAGS file to generate and no daemon to babysit.

The cost is that every jump runs a search. The package shells out to one of three tools, The Silver Searcher, ripgrep, or plain grep, and picks between them by an automatic fallback order. The documentation is direct about the consequence: it can be slow when it falls back to grep, or when the project is large.

The listed remedies are all about the searcher. Install ag, or install rg, or create a .dumbjump file in the project root listing directories to exclude. None of the remedies touch the pattern matching, because the matching is not the slow part.

The accuracy claim sits next to those speed warnings and is softer than either. For the currently supported languages, it says the package seems to do a good job of finding what you want, with a request to open an issue when it does not. There is no success rate figure, no test corpus and no comparison against a language server, so the claim cannot be checked from the documentation. Sixty-one entries are listed, several of which are markup, stylesheet, schema or build formats rather than programming languages.

## The release pipeline has a dry run and the last two tags are four years apart

The build system is unusually thorough for a single-file Emacs Lisp package, and the release half of it is scripted through the GitHub command line tool.

Every release variable is overridable from the environment: the repository, the branch, the version, a bump target, the tag, the notes file, and a switch for whether notes are generated. There is a dry-run target that passes a dry-run argument to a shell script, and a separate release-check target that runs before it. The tooling is set up so that you can rehearse an entire release, including note generation, and change nothing.

Having all that, the tag history is two releases in seven years before 2026. That combination is the thing to sit with. The automation was not the bottleneck, and neither was the package being dormant in any meaningful sense, since commits continued through June 2026 after the February 2026 tag.

The default target runs the test suite, which shells out to the Cask dependency manager and then to ert-runner through an .ert-runner configuration. Docker-based test runs take an Emacs version parameter defaulting to 29.4, so a specific older version can be requested from the command line.

## GNU make is detected, bmake warns, smake users are told to write their own file

The build control file checks for GNU Make specifically, using the make version variable, and includes a separate makefile only in that case. NetBSD bmake gets a warning on the include line and is told to ignore it. And there is a comment covering the remaining case in full: if support for smake is needed, a separate file should be written for it.

That is a build system documenting its own gaps rather than hiding them, and it explains why the file is structured the way it is. All the recipes are declared phony, with a comment above them explaining why: most recipes do not correspond to a file, so without the declaration a file of the same name would shadow the target.

At the root of the repository there is a copy of the licence, a Cask file, a directory-local variables file, documentation, a media directory for images, and a test directory. There are also three assistant configuration files side by side: a code review bot configuration, an agents file and a Claude file.

For an Emacs Lisp package with one main source file at the root, that is a lot of configuration surface, and it is the configuration that tells you what kind of project this is.

## Conclusion

Still the right choice if you want a jump command that needs no index build and no daemon, and if your Emacs is recent enough for the completing-read path to exist. What to check first is your Emacs version against the xref floor, and whether you want a live grep on every jump. If you have a large tree, install ag or rg before you blame the package, because the documented speedups are all about the searcher, not the matcher.

## FAQ

### What Emacs version does dumb-jump need?

GNU Emacs 26.1 or newer for the current version. Version 0.5.5 is the last release that supports Emacs 24 or 25, so anyone on an older Emacs must stay on that tag and lose everything documented in the usage section.

### Does dumb-jump build a symbol index like TAGS?

No. The design is explicitly to keep no stored indexes and no persistent background processes, running a live search with The Silver Searcher, ripgrep or grep on every jump instead. The stated remedy for slowness is to install ag or rg, or to list directories to skip in a .dumbjump file at the project root.

### How does dumb-jump find references across all languages without per-language rules?

Find references works by broad search rather than by language patterns. It searches for where a symbol is used and then filters out anything matching a definition pattern, which is why it is described as working for all the supported languages with zero additional configuration, unlike jump to definition which needs a rule set per file extension or major mode.

## Sources

- [Issues](https://github.com/jacktasia/dumb-jump/issues)
- [jacktasia/dumb-jump on GitHub](https://github.com/jacktasia/dumb-jump)
- [License: GPL-3.0](https://github.com/jacktasia/dumb-jump/blob/master/LICENSE)
- [README](https://github.com/jacktasia/dumb-jump/blob/master/README.md)
- [Releases](https://github.com/jacktasia/dumb-jump/releases)

---

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