Tldr:
- Grep is good but can be slow, especially when searching large codebases
- Try
ripgrep. It’s much faster and has convenient defaults
Grep
In large codebases just finding the things you need can be hard. The built-in solution on linux/unix is grep. The basic format is grep {search_term} {file_path}. Here are a few simple examples:
# This searches for the string "justin" in the file "package.json"
grep justin package.json
# Grep is case-sensitive by default, -i makes it case-insensitive
# So this will find "justin", "Justin", or "JUSTIN"
grep -i justin package.json
# Searches for "justin" in all files in my current directory
grep justin ./*
# "-r" means this will recursively search all directories
# which are children of the current directory.
# This one might take a while
grep -r justin ./*Here are a few commonly-used useful flags for grep:
| Flag | Effect |
|---|---|
| -i | makes search case-insensitive |
| -r | recursively search directories |
| -n | show the line number within the file where the match occurs |
| -l | return only the names of files where matches were found |
A quick example combining flags to search the infamous /node_modules directory:
pwd
# /repo/node_modules
# This will print every file name within /node_modules which
# contains a match for the string "justin", case-insensitive
grep -irl justin ./*When doing a search like this, however, grep is slow. I timed the search above via command line time and it took 34.3s, which is more than enough time to get distracted. I ran the same search with ripgrep and it finished in 3.4s; 10 times faster.
Ripgrep
Ripgrep is an open source alternative to grep, and it is fast.1 I used to worry about optimizing my grep searches to try and speed them up. With rg, I don’t even consider optimization, it’s pointless. Besides winning on speed, ripgrep also bakes in some convenient default search behavior:
- Searches the current directory without needing an additional argument
- Searches sub-directories, no
-rflag needed - Ignores anything in your
.gitignore, hidden files, and binary files - Has nicely organized and colorized output, for easier reading
Here’s my local output when running the same query in grep and then again in ripgrep. First, grep:

Now here’s ripgrep (rg). This is the same exact search, but rg doesn’t require the additional -i and -r flags, or the * telling it to search this directory:

Helpful Ripgrep configuration options
In the previous paragraph I mentioned that ripgrep doesn’t require the -i flag, but that’s not entirely true; I just have ripgrep set to --smart-case2 by default. Ripgrep supports a lot of configuration options, including the ability to specify a RIPGREP_CONFIG_PATH pointing to a file containing default options you want all the time. Here’s what’s in my config file, which I lifted directly from the example in the docs:
# Don't let ripgrep vomit really long lines to my terminal, and show a preview.
--max-columns=150
--max-columns-preview
# default all searches to smart case
--smart-caseZshRipgrep also supports just about every native grep flag. I often use -B or -A to show lines before and after a match for more context.
Conclusion
Grep is useful but slow. There are many open source alternatives to grep, but so far I haven’t found anything that beats ripgrep for pure speed and usability.
Notes
- Ripgrep’s README has a number of performance comparisons to other grep-like tools ↩︎
- Smart case means: “if the entire string is lowercase, the search is case-insensitive. If anything is uppercased, the search is now case-sensitive.” Just like Vim’s
:set smartcase↩︎
Helpful Links