rg.el: running ripgrep from inside Emacs without leaving the keyboard
Emacs search tool based on ripgrep
At a glance
- What is it?
- rg.el is an Emacs package that drives ripgrep and presents the results as a proper Emacs buffer, with grouping, a history of past searches, an isearch mode, and a Magit style transient menu. It is the kind of glue that changes how you use an editor, and the README is candid that version 2.0.0 changed the default key bindings.
- Who is it for?
- rg.el fits an Emacs user who has ripgrep installed and wants project-wide search to behave like a first-class editor command rather than a shell escape, and who is willing to learn a new set of key bindings. It is the wrong choice if ripgrep is not on the machine, since the package shells out to it, and it is the wrong choice if you want a GUI search that non-Emacs teammates can use.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 19 days ago.
- What is it written in?
- Mainly Emacs Lisp, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The premise is that ripgrep is fast and Emacs search is not
rg.el is an Emacs search tool based on ripgrep, and the README opens by explaining why ripgrep exists at all. Ripgrep is a replacement for both grep like tools, which search one file, and ag like tools, which search many files, and it is fast and versatile and written in Rust, with a link to the blog post that introduces it and includes benchmarks. The package then does the part that a bare binary cannot. It turns a recursive search over a codebase into an Emacs buffer you can move through, filter, and act on, with the same muscle memory you would use for any other buffer. The audience is an Emacs user who already has ripgrep on their path, and who wants project-wide search to feel like an editor feature rather than a shell command with a file listing in it.
Installing from MELPA is one command inside Emacs
The package is available on MELPA Stable and on MELPA, and the README gives the in-Emacs route, installing with `M-x package-install` <kbd>RET</kbd> `rg` from within Emacs. It is also available in GNU Guix as `emacs-rg`, with the command `guix package -i emacs-rg`. The Guix version listed in the link is 2.2.0, which is worth noting since the current release here is 2.4.1. For a manual install the instruction is to put `rg.el` and the rest of the elisp files somewhere in the load path and require the package:
``` el (require 'rg) ```
The next line is the detail that matters for anyone with a slow startup. `rg` and friends are autoloaded symbols, which means it is also possible to defer loading if you have autoloading setup. So the package does not force a load cost on you, but only if you arrange the autoloading yourself.
Default bindings are enabled eagerly unless you configure lazy loading
There are two ways to turn the package on, and the README is careful about the difference. The non lazy way is a single call:
``` el (rg-enable-default-bindings) ```
The README notes plainly that this sets up the default key bindings in a non lazy way, and that if you care about startup performance you should see the next example, which is the lazy loading guidance in the documentation. That is a real decision rather than a footnote. Binding the defaults is what makes ripgrep feel like part of Emacs, and it is also what costs you startup time, and the documentation at rgel.readthedocs.io is where the lazy variant is explained. The build status and coverage badges in the README, plus the ert-runner based test setup, suggest the package is developed with some care rather than thrown together.
Version 2.0.0 replaced the defaults, and old habits have an escape hatch
A package that changes its key bindings is a package that breaks muscle memory, and rg.el handled that openly. `rg.el` 2.0.0 will use new default settings to improve look and feel, with more consistent key bindings, and if you want the old defaults you add this to your `init.el`:
``` el (rg-use-old-defaults) ```
The release history shows how the project has moved since then, with 2.3.0 in March 2023, 2.4.0 in October 2025, and 2.4.1 in August 2026, and the last push was on 2026-10-04. The compatibility note is the one to remember. Anyone upgrading from a pre-2.0 configuration, or following an older tutorial, will find their keys doing something different, and the escape hatch exists for exactly that situation.
The menu mode borrows Magit's transient interface
There is a second front end for people who prefer a modal interface to key chords. If you prefer to use a Magit like interface as a complement to regular key maps, you replace `(rg-enable-default-bindings)` with `(rg-enable-menu)`. The menus are built with transient, which means that the menus can be modified in the same way as in Magit. That is a deliberate dependency on a specific transient version of the Magit ecosystem rather than a hand-rolled prefix menu, and it is the right call if you already use Magit, because the two then behave the same way. The repository layout shows a `rg-menu.el` file next to the core, and the project also ships `rg-ibuffer.el` for buffer integration and `wgrep-rg.el`, a bridge for the wgrep workflow of searching and editing results in place.
The file list shows a package that grew beyond a single command
The repository listing is more informative than the README about how much there is here. There is `rg.el` for the core, `rg-header.el` for the header line, `rg-history.el` for the search history, `rg-ibuffer.el` for the buffer, `rg-info-hack.el`, `rg-isearch.el` for an incremental search mode inside results, `rg-json.el`, `rg-result.el` for the result line handling, and `rg-menu.el` for the transient interface. There is also `wgrep-rg.el` and a `rgel.info` Info manual, with the README noting that Info documentation is included in the package and that the online documentation is at rgel.readthedocs.io. The `docs/` directory plus the Makefile targets for reStructuredText and HTML output, driven by Sphinx, show that the documentation is generated from org-mode sources in the repository.
Building the docs and tests runs inside a Nix container
The development setup is unusual and worth describing, because it shows how the test environment is pinned to specific Emacs versions. The Makefile defines `EMACS_VERSION=29-4` and a `DOCKER_IMAGE` built from it, and when `USE_DOCKER` is set every target is wrapped in a `docker run` with the working directory bind mounted, so the make invocation runs inside the container. The Dockerfile starts from ubuntu, installs curl, make, git, python3, ripgrep, sudo and the Sphinx toolchain, then installs Nix, cachix, and Emacs 28-2 from nix-emacs-ci, and cask. The documented contributor steps are to install cask, run `make deps` to install dependencies, and run `make test` for the tests. The `test` target is a chain of ert-test, style-check, package-lint, build-test, and package-test, and the style check uses the repository's own `test/style-check.el`.
Where rg.el is the wrong tool
Two limits are structural. The first is the hard dependency on ripgrep. The package is a front end for a binary that has to be on the path, so on a machine where ripgrep is not installed, rg.el does nothing, and in an environment where you cannot install binaries, that rules the package out entirely. The second is the audience. This is an Emacs Lisp package with Emacs Lisp key bindings and an Emacs Info manual, and there is no way to give the same interface to a colleague on a different editor. If the search needs to be available to a whole team, a project-agnostic tool that everyone runs the same way is a better answer. The narrower point is about the cost side of the trade. The package asks for a new key binding scheme, or at least a decision about whether to keep the old one, in exchange for a search experience that is genuinely better than shelling out. For a single user who lives in Emacs, that is a good deal. For a team with mixed tooling, it is a fork in the road.
Editorial conclusion
rg.el fits an Emacs user who has ripgrep installed and wants project-wide search to behave like a first-class editor command rather than a shell escape, and who is willing to learn a new set of key bindings. It is the wrong choice if ripgrep is not on the machine, since the package shells out to it, and it is the wrong choice if you want a GUI search that non-Emacs teammates can use. Before you adopt it, read the 2.0.0 release notes about the new defaults and decide whether you want `rg-use-old-defaults`, and check the lazy loading notes in the documentation, because binding the defaults eagerly is the thing the README warns about for startup time.
Frequently asked questions
How do I install rg.el in Emacs?
The package is on MELPA Stable and MELPA, so you can install it with `M-x package-install` RET `rg` from within Emacs. It is also available in GNU Guix as `emacs-rg`, installed with `guix package -i emacs-rg`, or you can put `rg.el` and the other elisp files in your load path and `(require 'rg)`.
Do I need ripgrep installed to use rg.el?
The package is an Emacs front end for ripgrep, so ripgrep has to be available on the machine. The README explains ripgrep as a replacement for both grep like and ag like tools, and the development Dockerfile installs ripgrep alongside the rest of the toolchain.
What changed in rg.el 2.0.0 and how do I keep the old behaviour?
Version 2.0.0 uses new default settings to improve look and feel with more consistent key bindings. If you want the old defaults you add `(rg-use-old-defaults)` to your `init.el`.
How do I enable the menu interface instead of key bindings in rg.el?
Replace `(rg-enable-default-bindings)` with `(rg-enable-menu)`. The menus are built with transient, so they can be modified in the same way as in Magit, and the README suggests the documentation for how to handle lazy loading if you care about startup performance.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/dajva-rg-el)Was this useful?