find vs grep — which command to search with, and why grep takes forever

You're looking for where the Checkout component is declared. You type grep -r Checkout . and wait. The terminal spits out thousands of lines from node_modules, the fan howls, no end in sight.
Then it turns out the file is simply called Checkout.tsx. A different command would have found it in a fraction of a second.
People mix up find and grep all the time. Both "search," both live in every Linux and macOS. But they search for completely different things. Let's see which to use when — and why AI agents keep both.
In short: the cover or the contents
Picture a library.
findwalks along the shelves and reads the spines: title, size, date. It never looks inside the books.grepopens the books and reads the pages. It looks for the phrase in the text.
Everything else follows from that. Know what the file is called — go to find. Know a word inside the file — go to grep.
find . -name "Checkout*" # files whose name starts with Checkout
grep -rn "function Checkout" . # lines where this text appears
Side by side
What it searches
- find — files and folders by name, type, size, modification date.
- grep — lines of text inside files.
What it returns
- find — a list of paths:
./src/Checkout.tsx. - grep — the path, the line number and the line itself:
src/api.ts:42: function Checkout(). With-l— file names only.
Speed
- find — fast. It doesn't open files, it only looks at the directory.
- grep — slower. It reads every byte of every file. In a project with
node_modules, that's hundreds of megabytes.
The main trap
- find — a pattern without quotes. The shell expands
find . -name *.jsbefore find ever sees it, and the search breaks. Write"*.js"in quotes, for the same reason as in why your script breaks on spaces. - grep — searching everything, including dependencies, build output and
.git. Hence the endless wait and thousands of junk lines.
What else it can do
- find — search by age and size:
find . -size +100Mfinds huge files,find . -mtime -1finds ones changed in the last day. - grep — search by regular expression, ignore case (
-i), show context around a match (-C 3).
How to combine them
The most useful searches use both at once. "Find a word, but only in TypeScript files":
grep -rn --include="*.ts" "Checkout" src/
"Find today's logs that had an error":
find logs/ -name "*.log" -mtime -1 -exec grep -l "ERROR" {} +
Here find picks files by name and date, and -exec hands them to grep to read. The same -exec trick comes in handy when you need to rename many files or do something else with them.
And most importantly — don't search where you don't need to:
grep -rn "Checkout" . --exclude-dir={node_modules,.git,dist}
What to install instead
Both commands have modern versions: fd instead of find and rg (ripgrep) instead of grep. By default they skip everything in .gitignore. So they don't touch node_modules or the build at all. And they're many times faster.
Here's a fun detail: in Claude Code the agent has exactly two search tools. Glob finds files by a name pattern — that's find. Grep searches text inside, and under the hood it's ripgrep. When an agent "explores the project," it does what you do: first it reads the spines, then opens the right books. More on searching big codebases in how to find code in a big project.
Who should use what
- Looking for a file and remember any part of its name —
find(orfd). Fastest of all. - Looking for where a function, an error message, or an API key is used —
grep -rn(or better,rg). - Looking for text, but only in files of a certain type or age —
find+greptogether, orgrep --include. - Working on a Node or Python project every day — install
rgandfdand forget about--exclude-dir.
If in doubt, start with grep -rl: it shows only the names of files with matches. A list of short paths is easier to read than a wall of lines.
Why does grep say "binary file matches"?
The match was found in a file that doesn't look like text: an image, an archive, compiled code. grep won't print that line so it doesn't flood your screen with junk. The -I flag skips such files entirely.
How do I find a file if I don't remember the letter case?
Use -iname instead of -name: find . -iname "readme*" finds both README.md and readme.txt.
Short story-lessons, an agent simulator and daily practice — in our mobile app. Free.





