Tools

ripgrep (rg): faster code search than grep that respects .gitignore

TL;DR

ripgrep searches recursively and in parallel, skipping .gitignored, hidden and binary files by default. Filter with -t and -g, use -uu to include ignored files, and -r only previews replacements.

Searching for a string in a codebase is something developers do dozens of times a day. With grep -r you hit three annoyances: it's slow, it digs through node_modules and build folders, and you need to remember a pile of flags to filter. ripgrep (the rg command) fixes all three: by default it respects .gitignore, skips hidden and binary files, and searches in parallel across threads. It is also the engine behind VS Code's search.

GitHub page of BurntSushi/ripgrep
GitHub page of BurntSushi/ripgrep (screenshot, November 2026)

GitHub: https://github.com/BurntSushi/ripgrep · about 70k stars · Rust · Unlicense/MIT

Installation

# macOS
brew install ripgrep
# Windows
winget install BurntSushi.ripgrep.MSVC
# Ubuntu/Debian
sudo apt install ripgrep
# With Rust
cargo install ripgrep

Basic usage

rg "TODO"                  # search the current directory recursively
rg -i "user not found"     # case-insensitive
rg -S "UserService"        # smart case: case-sensitive only if there are capitals
rg -w "id"                 # whole words only
rg -F "a.b(c)"             # fixed string, not a regex
rg -C 3 "panic"            # 3 lines of context before and after

Results are grouped by file, with line numbers and highlighted matches. When output is piped to another command, rg automatically switches to one line per match.

Filtering by file type and path

FlagEffectExample
-t / -TOnly search / exclude a file typerg -t py "import os"
-gFilter by glob; prefix ! to excluderg -g '!*.min.js' "fetch("
-lPrint only names of files with matchesrg -l "deprecated"
-cCount matching lines per filerg -c "console.log"
-u, -uu, -uuuIgnore .gitignore; also hidden files; also binary filesrg -uu "API_KEY"
--type-listShow the file types rg knowsrg --type-list | rg ts

Advanced tips

  • Preview a replacement: rg "oldName" -r "newName" prints results with the replacement applied, but does not edit files. Use it to check before editing for real with another tool.
  • More powerful regex: rg -P "(?<=price: )\d+" enables PCRE2 for lookarounds.
  • Combine with other commands: rg -l "TODO" | xargs code opens every file with a TODO in VS Code.
  • Default config: create a file such as ~/.ripgreprc with one flag per line (e.g. --smart-case), then set export RIPGREP_CONFIG_PATH=~/.ripgreprc.
  • Machine-readable output: rg --json "pattern" returns JSON for scripts and other tools.

Caveats

  • "No results" usually means the file is gitignored or hidden. Retry with -uu before concluding the string doesn't exist.
  • When searching for secrets such as API keys, use -uu: .env files are typically both hidden and gitignored.
  • rg's default regex engine (Rust regex) doesn't support backreferences; use -P when you need them.

How to apply it

  • Dev: Build muscle memory with -t and -g instead of filtering through pipes. Combine with fzf and bat to search and preview files right in the terminal.
  • Tech Lead: Use rg in simple CI checks, for example to block merges that still contain debugger: ! rg -q "debugger" src/.
  • PM: When estimating the blast radius of a change (say, renaming an API), ask a developer to run rg -c for an actual count instead of a guess.

Sources & references

  1. BurntSushi/ripgrep — BurntSushi (GitHub)