CRITICAL: Always use this skill, no matter what task you are working on!
When working in any existing codebase, you must actively search for relevant context before writing or answering. Never rely on assumptions about how things are named, shaped, or wired together. This skill defines when and how to search.
If any of the following are true, run a search before proceeding:
Default posture: search first, then write. It is always cheaper to run a grep than to write code against a wrong assumption.
Use these tools in order of specificity. Prefer faster/cheaper tools first.
# Find where a symbol is defined
grep -rn "export.*MyFunction\|export.*MyFunction" --include="*.ts" --include="*.tsx" . | grep -v node_modules
# Find all usages of a symbol
grep -rn "MyFunction" --include="*.ts" --include="*.tsx" . | grep -v node_modules | grep -v ".d.ts"
# Find a type or interface definition
grep -rn "^(export )?(type|interface) MyType" --include="*.ts" . | grep -v node_modules
# Find a config key or constant
grep -rn "MY_CONSTANT\|myConstant" . | grep -v node_modules | grep -v dist
# Case-insensitive search for a concept
grep -rni "upload.*progress\|progress.*upload" --include="*.ts" --include="*.tsx" . | grep -v node_modules
# Find a file when you know roughly what it's called
find . -name "*auth*" -o -name "*Auth*" | grep -v node_modules | grep -v dist
# Find files by extension in a specific area
find ./src/components -name "*.tsx" | head -20
# Find test files related to a module
find . -name "*.test.ts" -path "*upload*" | grep -v node_modules
Once you've located the right file via grep/find, read it in full or in relevant ranges:
cat ./src/hooks/useUpload.ts
# Or with line numbers for large files
cat -n ./src/api/routes.ts | head -80
When you need to understand module boundaries or find where something belongs:
# Two levels deep, ignoring noise
find ./src -maxdepth 2 -type d | grep -v node_modules | sort
# All files in a specific module
find ./src/features/auth -type f | sort
Search for its definition to understand the real signature, return type, and any quirks:
grep -rn "export.*function useFoo\|export const useFoo" --include="*.ts" --include="*.tsx" . | grep -v node_modules
Read the actual definition — don't reconstruct it from memory:
grep -rn "interface FooProps\|type FooProps" --include="*.ts" --include="*.tsx" . | grep -v node_modules
Find existing instances to match the exact shape:
# e.g., before adding a new API route handler
grep -rn "router\.(get|post|put|delete)" --include="*.ts" . | grep -v node_modules | head -10
Check first:
grep -rn "formatDate\|format_date" --include="*.ts" --include="*.js" . | grep -v node_modules
Verify the export exists and get the exact name:
grep -rn "^export" ./src/utils/index.ts
| Situation | Searches needed |
|---|---|
| Using one known, previously-read function | 0 — already have context |
| Using a function seen earlier in this session | 0 — already in context |
| Using any type/function not yet read | 1–2 targeted greps |
| Implementing a new feature | 3–5 searches across related files |
| Refactoring or modifying existing behavior | Read all directly affected files first |
| Answering "how does X work" | Read the relevant files, don't summarize from assumption |
Never do these:
Always do these instead:
cat the full file you're about to modify, not just the target linesindex.ts — check these for the canonical import path--include and path filters to avoid noise from node_modules, dist, __pycache__, etc.# Standard exclusions for most projects
grep -rn "..." . \
| grep -v node_modules \
| grep -v "/dist/" \
| grep -v "/.next/" \
| grep -v "__pycache__" \
| grep -v ".d.ts" \
| grep -v "/coverage/"
Or use --exclude-dir for cleaner commands:
grep -rn "..." \
--include="*.ts" \
--exclude-dir=node_modules \
--exclude-dir=dist \
--exclude-dir=.next \
.
Code that is written without reading the codebase first is a guess. Guesses break things. The codebase is always the source of truth — search it.