PROMPT TO PRODUCTION
Chapter 7 of 19 · 10 min read

Chapter 7: Search and Navigation

Quick Start (5 minutes)

Let’s find a bug using Glob and Grep. Imagine you’ve inherited a project and users report that the login endpoint sometimes returns a 500 error. You need to trace the problem.

Step 1: Find the authentication files

You: Glob **/*auth*.{js,ts}

Result:
  src/middleware/auth.js
  src/controllers/authController.js
  src/routes/authRoutes.js
  src/utils/authHelpers.js
  tests/auth.test.js

Step 2: Search for error handling in those files

You: Grep "catch|500|error" in src/controllers/authController.js
     (show content with 2 lines of context)

Result:
  src/controllers/authController.js:
  44:   } catch (error) {
  45:     console.error('Login error:', error);
  46:     res.status(500).json({ message: 'Server error' });

Step 3: Find where the login function calls external services

You: Grep "await" in src/controllers/authController.js (show content)

Result:
  25:  const user = await User.findOne({ email });
  31:  const isValid = await bcrypt.compare(password, user.password);
  38:  const token = jwt.sign({ userId: user._id }, JWT_SECRET);

Now you can see the problem: line 31 calls bcrypt.compare on user.password, but what if user is null (line 25 returned nothing)? The code doesn’t check for a missing user before accessing user.password, which throws a TypeError caught as a generic 500 error.

You just used Glob to find files by name and Grep to search content – the two core navigation tools in Claude Code.


Core Concepts (15 minutes reading)

7.1 File Search with Glob Patterns

Glob is Claude Code’s file pattern matching tool. It finds files by name patterns, not content.

Glob Pattern: A wildcard pattern for matching file paths, using special characters like *, **, ?, and [].

Basic syntax:

*           Matches any characters (except /)
**          Matches any characters (including / -- recursive)
?           Matches single character
[abc]       Matches one character: a, b, or c
{js,ts}     Matches either js or ts

Practical examples:

Glob **/*.js                    Find all JavaScript files
Glob src/components/**/*.tsx    Find all TSX files under src/components/
Glob **/*.test.{js,ts,tsx}      Find all test files
Glob **/*auth*.{js,ts}          Find all files with "auth" in the name
Glob src/*.ts                   Find TypeScript files in src/ only (not subdirs)

Strategy: Start broad, then narrow

Step 1: Glob **/*.js           All JS files (500 results -- too many)
Step 2: Glob src/**/*.js       Just src directory (200 results)
Step 3: Glob src/routes/*.js   Just routes (15 results -- useful)

Common Glob Patterns Reference

Pattern                         | Finds
--------------------------------|------------------------------------
**/*.js                         | All JavaScript files
src/**/*.tsx                    | All TSX files under src/
**/*.test.js                    | All test files
**/*Component*.tsx              | Components with "Component" in name
**/index.{js,ts}                | All index files
**/*.{json,yaml,yml,env}        | All config files

Tip: Glob is fast. Use it liberally to explore project structure and locate files by name.


7.2 Content Search with Grep

Grep searches file content (not filenames). It finds code, comments, or specific text using regular expressions.

When to use Glob vs. Grep:

Use Glob when:                  | Use Grep when:
Finding files by name           | Finding code by content
"Where's the config file?"      | "Where do we log errors?"
"Find all CSS files"            | "Find all TODO comments"

Basic usage:

You: Grep "validateUser" in src/

Result (files mode -- default):
  src/auth/authController.js
  src/middleware/auth.js
  src/utils/validation.js

You: Grep "validateUser" in src/ (show content)

Result (content mode):
  src/auth/authController.js:25:  const isValid = validateUser(user);
  src/middleware/auth.js:12:      import { validateUser } from '../utils';
  src/utils/validation.js:45:     export function validateUser(user) {

Case-insensitive search:

You: Grep "password" (case-insensitive) in src/

Matches: "Password", "password", "PASSWORD"

With context lines:

You: Grep "validateUser" with 3 lines before and after

Shows the function call with surrounding code, helping you
understand how it's used in each location.

Grep Output Modes

  1. Files With Matches (default) – just file paths. Use when you need to know which files.
  2. Content Mode – shows matching lines with line numbers. Use when you need the actual code.
  3. Count Mode – number of matches per file. Use to estimate scope before diving in.

Grep Best Practices

Scope your search:

Bad:  Grep "error" in ./       (10,000+ matches)
Good: Grep "error" in src/auth/ (50 relevant matches)

Use file type filters:

Grep "validateUser" in *.js files only
(Excludes .json, .md, .txt, images, binaries, build outputs)

Escape special regex characters:

Grep "app.use"    Matches "app.use", "appause", "appouser"
Grep "app\.use"   Matches only "app.use"

7.3 Combining Glob and Grep

The real power comes from combining both tools.

The search workflow:

1. Use Glob to find relevant files
2. Use Grep to search within those files
3. Use Read to examine specific files in detail
4. Use Edit to make changes

Example: Finding and replacing all console.log statements

Step 1: Grep "console\.log" in src/ (count mode)
        Result: 20 matches across 8 files

Step 2: Grep "console\.log" in src/ (show content)
        Result: See each console.log with its context

Step 3: Read specific files to understand which logs to keep

Step 4: Replace debug console.logs with proper logger

Example: Understanding a feature you didn’t write

Goal: Understand how "password reset" works in an unfamiliar codebase

Step 1: Glob **/*password*reset*.{js,ts}    (find related files)
Step 2: Grep "password.*reset|reset.*password" (case-insensitive)
Step 3: Grep "POST.*reset" in routes/        (find entry point)
Step 4: Read the route -> controller -> service files in sequence

Result: Complete understanding of the feature flow in 5 minutes.

Example: Security audit

Step 1: Grep "SELECT.*FROM|INSERT INTO" in src/    (find SQL queries)
Step 2: Grep "req\.(body|params|query)" in src/    (find user input handling)
Step 3: Grep "authenticate|authorize" in src/       (find auth checks)
Step 4: Review each finding for vulnerabilities

7.4 Understanding Unfamiliar Codebases

When you join a new project, systematic exploration is crucial. Here’s a framework.

Phase 1: Get the lay of the land (5 minutes)

Step 1: List main directories
Step 2: Glob **/index.{js,ts} or **/main.{js,ts}    (find entry points)
Step 3: Read package.json                             (deps, scripts, project name)

Phase 2: Identify key components (10 minutes)

Step 4: Glob **/app.{js,ts} or **/server.{js,ts}     (main app file)
Step 5: Glob **/routes/** or Grep "Router|route"      (routing)
Step 6: Glob **/models/** or **/schemas/**             (data models)
Step 7: Glob **/controllers/** or **/services/**       (business logic)

Phase 3: Understand patterns (15 minutes)

Step 8:  Ask Claude to analyze the project organization
Step 9:  Grep "export function|export class" in src/ (count)
Step 10: Glob **/*.{test,spec}.{js,ts,tsx}            (test files)
Step 11: Glob **/README.md or **/docs/**              (documentation)

Result: In 30 minutes, you know the tech stack, project structure, main features, data flow, and development workflow.


7.5 The Search Decision Tree

What are you looking for?

-- File by name/pattern?  -->  Use Glob
   "Find all test files"

-- Code by keyword?  -->  Use Grep
   "Find all TODO comments"

-- Understanding a feature?  -->  Ask Claude Code to explore
   "How does authentication work?"

-- Specific function/class?
   Know rough location?  -->  Glob + Grep
   No idea where?       -->  Grep project-wide
   Need full context?   -->  Ask Claude to trace the flow

Try This Now

Exercise 1: File Exploration

In any project you have locally, run these commands:

  1. Glob **/*.{js,ts,tsx} – how many source files exist?
  2. Glob **/index.{js,ts} – where are the entry points?
  3. Glob **/*.test.{js,ts} – where are the tests?

Map out the project structure from just these three searches.

Exercise 2: Bug Hunt

Pick a project and try this workflow:

  1. Grep "TODO|FIXME|HACK" in src/ – find all technical debt markers
  2. Pick the most interesting one
  3. Use Grep with context lines to understand the surrounding code
  4. Read the full file to understand the fix needed

Deep Dive (optional, for mastery)

Using AI Agents for Complex Exploration

For complex questions that span multiple files, you can ask Claude Code directly rather than running individual Glob/Grep commands.

When to use agent exploration:

  • Understanding how a feature works across multiple files
  • Tracing code flow through multiple layers (route -> controller -> service -> database)
  • Finding code patterns that require understanding context and relationships

Example:

You: How does the authentication and authorization system work
     in this codebase? Trace the complete flow from login to
     protected routes.

Claude will systematically search for auth routes, trace middleware, identify token handling, and map protected route patterns – synthesizing findings into a coherent explanation.

When Glob/Grep is better: You know exactly what you’re searching for, you want quick results, or you want to minimize context usage.

When agents are better: You need understanding and synthesis, not just file locations.


Regex Quick Reference

Regular expressions power Grep searches. Here’s what you need most often.

Basic patterns:

.          Any character (except newline)    "a.c" matches "abc", "axc"
*          0 or more of previous             "ab*c" matches "ac", "abc", "abbc"
+          1 or more of previous             "ab+c" matches "abc" (not "ac")
?          0 or 1 of previous                "ab?c" matches "ac", "abc"
^          Start of line                     "^import" = line starts with "import"
$          End of line                       ";$" = line ends with semicolon
|          OR                                "cat|dog" matches either
()         Grouping                          "(export\s+)?function"
[abc]      Character class                   matches "a", "b", or "c"
\          Escape special character          "\." matches literal period

Character classes:

\d    Digit [0-9]             \w    Word character [a-zA-Z0-9_]
\s    Whitespace              \b    Word boundary

Common code patterns:

"(TODO|FIXME|HACK):?"                          TODO comments
"console\.(log|error|warn)"                    Console statements
"import.*from ['\"]express['\"]"               Express imports
"(export\s+)?(async\s+)?function\s+\w+\s*\("  Function definitions
"process\.env\.\w+"                            Environment variables

Pro tip: Test patterns incrementally. Start with "function", then add "\s+\w+", then "\s*\(".


When Things Go Wrong

Search returns too many results

Problem: Grep "error" in ./ returns 47,523 matches

Fix: Narrow your scope and be more specific:

Grep "error" in src/auth/           (specific directory)
Grep "new Error\(" in src/          (specific pattern -- error creation)
Grep "console\.error" in src/       (specific context)

Grep regex doesn’t match expected patterns

Problem: Grep "function test(" returns nothing, but you can see the function

Fix: Your code might use different styles:

export function test() { }       // Has "export " prefix
export async function test() { } // Has "async" keyword
const test = () => { }           // Arrow function -- no "function" keyword

Use a flexible pattern:

Grep "(export\s+)?(async\s+)?function\s+test\s*\("

Or search incrementally: start with Grep "test", then add specificity.

Search misses files due to .gitignore

Problem: Glob **/*helper*.js returns nothing, but the file exists

Fix: Glob respects .gitignore by default. Common exclusions: node_modules/, dist/, build/, .env. Check with ls to confirm the file location, then verify it’s not in .gitignore.

Prevention: Start with a broad pattern (Glob **/*.js) to see what’s visible, then narrow down.

Case sensitivity catches you off guard

Problem: Grep "TODO" finds 5 matches, but you see "todo" and "Todo" too

Fix: Use case-insensitive search:

Grep "TODO" in src/ (case-insensitive)

Use case-insensitive for comments and common terms. Keep case-sensitive for specific identifiers (MyClass vs myClass).

Grep hangs or returns nothing

Possible causes: Searching extremely large files, complex regex causing backtracking, or infinite symlink loop.

Fix: Scope to a specific directory, simplify your regex, and check how many files you’re searching with Glob **/*.js (count) first.


Chapter Checkpoint

What you learned:

  • Glob finds files by name pattern; Grep finds code by content
  • Combine both: Glob to locate files, Grep to search within them, Read to examine
  • Scope searches to relevant directories to avoid drowning in results
  • Systematic codebase exploration follows a predictable 30-minute framework
  • Regex patterns let you find specific code constructs (functions, imports, TODOs)

You can now:

  • Find any file in a project using Glob patterns
  • Search for specific code, functions, or patterns using Grep
  • Trace a bug through multiple files using combined search strategies
  • Explore and understand an unfamiliar codebase in under 30 minutes
  • Choose the right search tool for the task (Glob, Grep, or agent exploration)