Verdict: install it today. If you search code from a terminal more than once a week, ripgrep (rg) is worth the thirty seconds it takes to install. It’s for people who type grep -rn reflexively and have made peace with the fact that it’s slow on big repos. It is not for people who need their scripts to run on a stranger’s locked-down server. More on that below.
ripgrep is a recursive search tool written in Rust. It’s free and open source (dual-licensed MIT / Unlicense). We have no relationship with the project, no affiliate link, and nothing to sell you. It’s a binary that finds text in files.
Install
brew install ripgrep # macOS
sudo apt install ripgrep # Debian/Ubuntu
cargo install ripgrep # anywhere with Rust
The package is ripgrep. The command is rg. Yes, that trips people up the first time.
What it actually does well
It’s fast, and it has defaults you’d otherwise have to type out by hand.
Search every file under the current directory for TODO:
rg TODO
That prints matching lines, grouped by file, with line numbers and color, recursively, automatically. The grep equivalent is grep -rn --color=auto TODO ., and it’ll be slower.
Filter by file type. Find def login only in Python files:
rg -t py 'def login'
-t py matches Python files by extension and a few other rules, so you don’t write a glob. There’s a -T to exclude a type, too. If you’d rather use a glob, -g '*.py' works.
Show three lines of context around each hit, case-insensitively:
rg -i -C 3 'connection refused'
src/net/pool.rs
42- let socket = TcpStream::connect(addr)
43- .await
44- .map_err(|e| {
45: warn!("connection refused: {e}");
46- Backoff::reset()
47- });
A few flags worth memorizing: -i case-insensitive, -C N context lines, -l print only filenames that match (great for piping into another command), -g for globs. By default rg is smart-case: an all-lowercase pattern matches case-insensitively, but the moment you type a capital letter it switches to case-sensitive. This is the right behavior most of the time and the wrong behavior exactly when you forget it exists.
The one default that will confuse you
ripgrep respects your .gitignore by default. It also skips hidden files and .git/ directories.
This is genuinely useful — you stop matching against node_modules/, build output, and minified vendor blobs without configuring anything. It’s also the single thing that will make you file a bug report against your own brain. You’ll search a repo for a string you know is in there, get nothing, and quietly lose faith in the tool. The string was in a .gitignored file. The tool worked perfectly. That was the problem.
The fix is to tell it to look everywhere:
rg --no-ignore --hidden 'API_KEY' # ignored + hidden files
rg -uu 'API_KEY' # shorthand for the same idea
-u relaxes one layer of filtering, -uu relaxes more (ignore rules and hidden files), and -uuu also reads binary files. Learn -uu. It’s the escape hatch for “why isn’t it finding the thing.”
When plain grep is still the right call
We are not telling you to delete grep. There are real cases where it wins:
- It’s already there. Every Unix-like machine has
grep. Nothing to install, nothing to explain to a teammate. - Tiny one-off pipes.
ps aux | grep sshis muscle memory and there’s no repo to recurse. Reaching forrghere buys you nothing. - Scripts you ship elsewhere. If a shell script has to run on machines you don’t control,
grepis POSIX and portable.rgflags like-tand-uuare ripgrep-only — they’ll fail on a box that doesn’t have it installed.
Use the fast tool for your own searching. Use the portable tool in code other people run.
What made us close the tab
Almost nothing — and that’s the honest part of an honest review. The only real gotcha is the .gitignore default catching newcomers, and once you know -uu exists, it stops being a problem and starts being a feature. There’s no telemetry, no account, no paid tier dangling a “pro” search behind it.
When it goes wrong: your search comes back empty and you’re sure the text is there. Nine times out of ten it’s in a gitignored or hidden file. Re-run with rg -uu. The tenth time, check your smart-case — a stray capital letter in the pattern turned off case-insensitivity.
Install it, search a repo, then forget it’s not built in. That’s the whole pitch.