# ripgrep: recursive regex search that respects your gitignore

> ripgrep is a Rust command line search tool that walks a directory tree, skips gitignored and hidden files by default, and applies a regex engine tuned for literal prefixes. It is fast, it is not a drop-in replacement for every grep invocation, and its defaults are the part that surprises people.

**BurntSushi/ripgrep** — ripgrep recursively searches directories for a regex pattern from the command line, respecting gitignore rules and skipping hidden and binary files by default.

- Repository: https://github.com/BurntSushi/ripgrep
- Stars: 68,707 · Forks: 4,129
- Language: Rust
- License: Unlicense
- Published: 2026-08-08 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/burntsushi-ripgrep

## The problem ripgrep solves: searching code without searching junk

Plain grep answers the question "does this pattern appear in these bytes" and leaves the file selection to you. On a source tree that means piping find into xargs, remembering to exclude .git, node_modules and build output, and re-deriving the same exclusions on every machine. ripgrep moves that decision into the tool. The README states that by default it respects gitignore rules and automatically skips hidden files, directories and binary files. The audience is anyone who greps a repository: application developers, reviewers reading unfamiliar code, and people wiring a search step into an editor or an agent.

The second problem is speed on large inputs. The README's benchmark tables compare ripgrep against ack, The Silver Searcher, ugrep, git grep and GNU grep on the Linux kernel source tree and on a roughly 13GB decompressed subtitle file. The author attaches a warning to those numbers, writing "Please remember that a single benchmark is never enough," and points to a longer blog post. That caveat matters more than the headline ratios, because the same README shows ripgrep's own numbers degrading when a pattern offers no literal text to anchor on.

ripgrep sits in the same category as ack and The Silver Searcher, which the README names explicitly. The difference in scope is that ripgrep is a single Rust binary with no runtime dependency, and the same engine is exposed as a library through the crates in the workspace.

## Inside the binary: a workspace of crates, not one big matcher

Cargo.toml defines a workspace whose members are globset, grep, cli, index, matcher, pcre2, printer, regex, searcher and ignore. The binary target is named rg and its entry point is crates/core/main.rs. The top-level package depends on grep, ignore, bstr, lexopt, log, serde_json, termcolor and textwrap. Those names describe the data flow: the ignore crate decides which paths are candidates, the searcher crate reads them, the matcher crate applies the pattern, and the printer crate formats the result for a terminal or for a machine.

The ignore crate is the piece that produces ripgrep's most visible behaviour. It resolves .gitignore, .ignore and .rgignore files, and the README lists all three as sources of filtering. Because filtering is a separate stage, it can be turned off wholesale with rg -uuu, which the README describes as disabling all automatic filtering by default. There is also a grep-index crate listed as an optional workspace member, which suggests an index-backed search path exists in the codebase; the README does not document it as a user-facing feature.

Regex handling comes from the regex crate, whose syntax the README links to at docs.rs. A separate pcre2 crate exists for patterns that need PCRE2 features such as lookaround, which the default engine does not support. That split is a design decision worth understanding: the default engine is chosen for predictable linear-time matching, and you opt into the backtracking engine when you need its expressiveness.

## Installing ripgrep with cargo, Homebrew or a release binary

The README's installation section is the authority here, and it lists several routes. The crates.io badge links to the ripgrep crate, so cargo install works for anyone with a Rust toolchain. The Cargo.toml sets rust-version = 1.96 for the workspace and edition = 2024, so an older toolchain will refuse to build it.

```bash
cargo install ripgrep
```

That command compiles the current published version and places an rg binary in your cargo bin directory. Expect a build rather than a download, since cargo resolves and compiles the workspace dependencies.

The README states that binary downloads are available for every release, and the repository carries a HomebrewFormula directory, which is where the macOS and Linux Homebrew packaging lives.

```bash
brew install ripgrep
```

After either route, rg --version should print the version. The README also links shell completions from the FAQ and a configuration file section in GUIDE.md, which is where per-user defaults belong rather than in a shell alias.

A first real use is the one the README opens with: search the current directory for a regex while filtering ignored files.

```bash
rg -n -w '[A-Z]+_SUSPEND'
```

This is the exact command from the README's first benchmark table. The -n flag adds line numbers and -w restricts matches to whole words. On a source tree you should see only tracked, non-hidden, non-binary files in the output. If a file you expected is missing, that is the ignore layer at work, not a failed match.

## Where ripgrep is the wrong tool

The defaults that make ripgrep pleasant interactively make it dangerous in scripts. A pipeline that assumes every file under a directory is searched will silently miss anything matched by a .gitignore rule, any dotfile, and any file the tool classifies as binary. The README offers rg -uuu as the escape hatch, but reaching for it everywhere discards the main reason to use ripgrep. If you need unfiltered, predictable recursion, GNU grep -r with explicit --include patterns is a smaller surprise.

Performance is not uniform either. The README publishes its own worst cases. Searching the subtitle corpus for '[A-Za-z]{30}', a pattern with no literal anchor, takes ripgrep 15.569s, and the same query under a Unicode locale takes GNU grep 8m30s. A separate table shows ugrep at 28.973s on a pattern where ripgrep finishes in 1.053s. The lesson is that "ripgrep is fast" is a statement about patterns with extractable literals; a pathological regex can put it in the same slow category as everything else.

Regex dialect is the third boundary. The default engine follows the syntax documented for the regex crate, which is not the same as POSIX ERE, and the README points readers to the FAQ for the question of whether ripgrep can truly replace grep. If your script depends on GNU-specific regex behaviour or on grep's exact exit codes and flags, ripgrep is a rewrite, not a swap.

## ripgrep vs grep: what actually differs

GNU grep is a byte-stream filter. You give it files or standard input, and it reports matches. Recursion is opt-in via -r, and it has no concept of a gitignore file. git grep is the closest alternative in spirit: it searches tracked content in a repository and knows about the index, so it can search a specific revision with a commit argument. Its approach is repository-first; ripgrep's is filesystem-first, which means it also works outside a repository and can search untracked files that git grep will not see unless you pass extra flags.

ugrep appears repeatedly in the README's tables and is the nearest feature competitor, offering recursive search with ignore-file handling and its own include and exclude flags. The README's equivalent-work comparison shows ripgrep at 0.063s against ugrep at 0.607s on the same corpus with matching filters, and a different table shows ugrep ahead of GNU grep. Those numbers come from the project's own README, so treat them as the author's measurements rather than neutral ones.

The Silver Searcher and ack occupy the same niche with a different implementation language. In the README's kernel-tree benchmark, ack reports 2677 lines against ripgrep's 536 for the same pattern and word boundary, which points at a difference in what each tool considers a match, not just how fast it runs. That is the kind of discrepancy worth resolving before you migrate a saved query between tools.

## Maintenance, licensing and what an upgrade costs

The repository is not archived, and the most recent push recorded here is 2026-07-15, which is also the timestamp of release 15.2.0. The two releases before it, 15.1.0 and 15.0.0, are dated 2025-10-22 and 2025-10-16. The gap between the 15.0.0 and 15.2.0 lines is roughly nine months, and the jump from 15.0.0 to 15.1.0 happened within a week, so the cadence is uneven rather than steady. Anyone tracking versions should read CHANGELOG.md, which the README points to as the release history, and the repository also carries a RELEASE-CHECKLIST.md that describes the maintainer's process.

Upgrade cost depends on how you consume it. A cargo install builds from source, so the Rust toolchain floor matters: Cargo.toml sets rust-version = 1.96 and edition = 2024, which means an older compiler cannot build the current release. A Homebrew or release-binary install avoids that entirely. Major-version bumps are where flag behaviour is most likely to shift, and the README does not promise flag stability across them.

Licensing is dual: the README states the project is dual-licensed under MIT or the UNLICENSE, Cargo.toml records license = "Unlicense OR MIT", and the repository carries LICENSE-MIT, UNLICENSE and COPYING files. For most consumers that is permissive and low-friction, but the choice is not uniform across the tree: the workspace pulls in third-party crates such as anyhow, bstr, lexopt, log, serde_json, termcolor and textwrap, and on musl 64-bit targets tikv-jemallocator, each under its own terms. If you redistribute a binary, audit the dependency licences rather than the top-level one. This is a description of what the files say, not legal advice.

## Conclusion

Adopt ripgrep if you search source trees interactively and want gitignore-aware defaults; skip it if you need POSIX grep semantics inside a script that runs on a minimal system, where GNU grep or git grep is already present. Before standardising on it, verify two things on your own corpus: whether the automatic filtering hides files you expected to match (run the same query with rg -uuu and compare), and whether your build environment can produce Rust 1.96, since Cargo.toml sets rust-version = 1.96 for the workspace. Check the CHANGELOG.md entry for the release you install rather than assuming flag behaviour is stable across major versions.

## FAQ

### What is ripgrep used for?

It is a line-oriented search tool that recursively searches the current directory for a regex pattern. By default it respects gitignore rules and skips hidden and binary files, which makes it suited to searching source trees.

### Is ripgrep better than grep?

The README presents benchmark tables where ripgrep finishes ahead of GNU grep on the same corpus, but it also states that a single benchmark is never enough and links to the FAQ on whether ripgrep can truly replace grep. The regex dialect and default filtering differ, so it is not a drop-in swap.

### Why is ripgrep so fast?

The README attributes results to benchmarks on the Linux kernel source tree and a large text corpus, and the workspace separates the ignore, searcher, matcher and printer crates. The README also documents performance cliffs when a pattern offers no literal optimization.

### How do I install ripgrep on Windows, macOS or Linux?

The README states that binary downloads are available for every release, and the crates.io badge points to the ripgrep crate for cargo install. The repository also carries a HomebrewFormula directory for Homebrew packaging.

### How do I use ripgrep to search a directory?

Run rg with a pattern; it searches the current directory recursively by default. The README's opening example is rg -n -w '[A-Z]+_SUSPEND', where -n shows line numbers and -w requires whole-word matches.

### How do I install ripgrep on Ubuntu?

The README lists installation routes including the crates.io crate for cargo install and binary downloads for every release. It does not document a distribution package name for Ubuntu.

## Sources

- [Official README](https://github.com/BurntSushi/ripgrep#readme)
- [Project repository](https://github.com/BurntSushi/ripgrep)
- [Release notes](https://github.com/BurntSushi/ripgrep/releases)

---

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