Working with Claude Code CLI
Claude Code is a terminal-based agentic coding assistant built by Anthropic. Unlike chat-based AI tools where you copy-paste code back and forth, Claude Code runs directly in your terminal, reads your actual codebase, executes commands, edits files, and iterates on its work until a task is complete. It is not just an AI that writes code — it is an AI that uses tools to accomplish coding tasks autonomously.
What Claude Code Actually Does
When you give Claude Code a task, it uses a set of tools to work through the problem:
- Read files — It scans the codebase to understand structure, conventions, and existing patterns
- Edit files — It makes targeted edits across multiple files simultaneously
- Run commands — It executes shell commands: running tests, linting, checking types, running migrations
- Glob and grep — It searches for patterns across the codebase to find relevant code
- Web fetch — It can retrieve documentation or API references when needed
This agentic loop — read, edit, run, verify — means Claude Code can handle tasks that would take a developer multiple steps and tool switches. It can add a feature, run the tests, see them fail, diagnose the failure, fix it, and run the tests again, all without you intervening.
Agentic Coding Patterns
The key shift when working with Claude Code is learning to describe outcomes rather than steps. Traditional pair programming guidance sounds like "open this file, change this function, update this import." Agentic prompting sounds like "add pagination to the courses list — it should show 10 items per page, use cursor-based pagination, and update the existing API route."
Claude Code will figure out which files to read, which to edit, and how to verify the change worked. Your job is to describe the goal clearly.
Effective agentic pattern:
- Describe the feature or fix in terms of user-observable behavior
- Mention any constraints (don't break existing tests, maintain the existing API shape, match the existing code style)
- Let Claude explore the codebase to find the relevant code
- Review the changes when complete rather than directing each step
Less effective pattern:
- Listing specific files to edit (unless you know the codebase is large and Claude needs direction)
- Asking for partial implementations ("just do the frontend, I'll handle the backend")
- Interrupting Claude's agentic loop with micro-corrections mid-task
Plan Mode: Think Before Acting
Claude Code has a plan mode (activated with Shift+Tab to toggle to "Plan" or by asking Claude to "plan before acting") that changes its behavior. Instead of immediately editing files, it first describes what it intends to do and waits for your approval before proceeding.
Use plan mode when:
- The task involves deleting or significantly restructuring files
- You are working with production configuration
- The change spans more than 5-6 files and you want to review the scope
- You are uncertain about the approach and want to validate the strategy first
Use direct execution when:
- The task is well-scoped and you trust the direction
- You are making additive changes (adding a new component, writing a new test)
- You have done the same kind of task before and know the pattern
Plan mode is especially valuable for refactoring tasks. A prompt like "refactor the authentication flow to use React context instead of prop drilling" touches many files. Seeing Claude's plan first lets you catch scope issues — maybe it intends to modify files you want left alone — before any edits happen.
Parallel Task Execution with Background Agents
Claude Code supports running multiple agents in parallel using the /agents command. This is powerful for tasks that are independent of each other but collectively make up a larger goal.
For example, if you need to update three unrelated components, you can launch three background agents, each handling one component. They run concurrently, each with their own tool access, and you can check in on progress or review results when they finish.
When to use parallel agents:
- Independent tasks that do not share files or state
- Running multiple tests or lint checks simultaneously
- Generating boilerplate for several new modules at once
- Performing research in one agent while implementing in another
When to avoid parallel agents:
- Tasks that depend on each other's output
- Changes to the same file from multiple agents (creates conflicts)
- Tasks where the second task's approach depends on the first task's outcome
# Launch a background agent for an independent task
> /agents
# Example: ask Claude to run two independent tasks
"In one agent, add unit tests for the UserProfile component.
In another agent, add unit tests for the CourseCard component.
These components are independent — run both in parallel."
Slash Commands and Workflow Controls
Claude Code's slash commands let you control its behavior without leaving the terminal:
/clear— Start a fresh context. Use this between unrelated tasks to prevent context from earlier conversations affecting later ones./compact— Summarize and compress the current conversation context. Useful for long sessions where you have explored multiple approaches and want to reset to a clean working state without losing progress./cost— Check token usage for the current session. Helps you understand when a task has become expensive and whether to adjust your approach./doctor— Run a diagnostic to verify Claude Code's environment and tool access./review— Ask Claude to review its own recent changes, catching issues before you do./init— Generate a CLAUDE.md file for the current project based on its structure./memory— Edit project or user memory files directly from the CLI./agents— Manage background agents for parallel work.
Practical workflow tips:
Keep tasks focused. Claude Code performs best when a single session has a single goal. "Add pagination and update the design system and fix the auth bug" is three tasks — run them as three sessions with /clear between each.
Verify before and after. Before a large change, ask Claude to describe its plan. After, ask it to run the tests and confirm nothing is broken. These verification steps are low-cost and prevent surprises.
Use git as a safety net. Commit before starting a large agentic task. If Claude's changes go in an unexpected direction, you can reset cleanly.
CLAUDE.md Files: Giving Claude Persistent Context
CLAUDE.md files are special markdown files that Claude Code reads automatically when it starts up. They provide persistent project context — architecture decisions, naming conventions, file locations, build commands — so you don't have to repeat this information in every prompt.
Claude Code reads CLAUDE.md files from three locations, in this order of precedence:
- Repository root —
CLAUDE.mdat the root of the git repo. Contains repo-wide conventions, architecture overview, and build commands. - Current directory —
CLAUDE.mdin the working directory. Contains directory-specific patterns and conventions. - User home —
~/.claude/CLAUDE.mdfor personal preferences that apply across all projects.
A well-structured CLAUDE.md typically includes:
# CLAUDE.md
## Build & Development Commands
npm run dev # Start development server
npm run build # Production build
npm run test # Run test suite
npm run lint # Run linter
## Architecture
- Next.js App Router with TypeScript
- Supabase for database and auth
- Tailwind CSS for styling
- Components in src/components/, organized by feature
## Conventions
- Use named exports, not default exports
- Use TypeScript strict mode — no `any` types
- React components use function declarations, not arrow functions
- Tests go in __tests__/ directories adjacent to the code they test
## Key Paths
- API routes: src/app/api/
- Shared components: src/components/ui/
- Database types: src/types/database.ts
The more accurate your CLAUDE.md is, the less you need to explain in individual prompts. Claude will follow the conventions documented there automatically — using the right import style, placing files in the right directories, and running the correct test command.
Nesting CLAUDE.md files is a powerful pattern for large monorepos. The root CLAUDE.md covers repo-wide standards, while each app or package directory has its own CLAUDE.md covering app-specific conventions. Claude reads all of them and applies the most specific guidance.
Hooks: Automating Pre and Post Actions
Claude Code supports hooks — custom commands that run automatically before or after Claude takes certain actions. Hooks are configured in your .claude/settings.json file and let you enforce workflows without remembering to ask.
Common hook use cases:
- Pre-edit hook: Run a formatter on files before Claude edits them, ensuring Claude works with consistently formatted code
- Post-edit hook: Run linting or type-checking after every file edit, catching issues immediately
- Pre-commit hook: Run the full test suite before Claude creates a commit
Hooks configuration lives in .claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hook": "npm run format -- $CLAUDE_FILE_PATH"
}
],
"PostToolUse": [
{
"matcher": "Edit|Write",
"hook": "npx eslint $CLAUDE_FILE_PATH --fix"
}
]
}
}
Hooks bridge the gap between Claude's autonomous work and your team's workflow requirements. Instead of ending every prompt with "and run the linter," you configure the hook once and it runs every time.
Multi-File Editing: Describing Changes Across Files
Claude Code handles multi-file changes well when you describe the change at the feature level rather than the file level. A prompt like "rename the UserProfile component to ProfileCard everywhere it's used" will cause Claude to find all usages, rename the file, update imports, and check for string references — you do not need to enumerate every file.
For more complex cross-file changes, providing a brief architectural note helps Claude make consistent decisions:
Refactor the authentication flow to use a new AuthContext instead of passing
user props through the component tree. The AuthContext already exists in
src/contexts/AuthContext.tsx. Update all components under src/features/
that currently receive a `user` prop to use useAuth() instead. Do not
change any components in src/components/ui/ — those should remain prop-driven.
This gives Claude a clear scope (what to change), a reference point (where the context lives), and an explicit boundary (what not to touch).
When to Be Specific vs Let Claude Explore
The right level of specificity depends on two factors: how large the codebase is, and how confident you are about where the relevant code lives.
Let Claude explore when:
- The codebase is medium-sized and well-structured
- You are not sure exactly where a bug originates
- You want Claude to find the idiomatic approach used elsewhere in the project
- The task involves understanding existing patterns before making changes
Be specific when:
- The codebase is very large and Claude might waste time searching
- You know exactly which file and function needs to change
- You want to prevent Claude from making changes in certain areas
- The task is surgical (fix this one thing, touch nothing else)
A practical middle ground: give Claude the starting point, then let it explore. "The bug is in the payment flow — start with src/features/checkout/ and trace from there" is better than either "edit src/features/checkout/PaymentForm.tsx line 47" or "find the payment bug" with no direction.
Example: Effective Claude Code Task Prompts
Feature addition (agentic, multi-file):
Add a "recently viewed" section to the course listing page that shows the
last 3 courses the user visited. Store viewed course IDs in localStorage
using a custom useRecentlyViewed hook. The hook should:
- Accept a courseId parameter
- Record it in localStorage under the key "recentlyViewed"
- Return the list of recent course objects (look up from the existing
courses data structure)
- Limit to the 3 most recent, most recent first
- Deduplicate: viewing the same course twice doesn't add it twice
Place the hook in src/hooks/. Add the recently viewed section to the
top of src/features/courses/CourseList.tsx, above the main course grid.
Match the existing card style used in that file.
After implementing, run npm test to verify no existing tests broke.
Bug fix (specific starting point):
There's a race condition in the auth redirect logic. When a user signs in
and is redirected to /dashboard, they sometimes briefly see the login page
before the redirect completes. Start with src/app/auth/callback/route.ts
and trace the redirect flow. The fix should prevent any flash of the login
page for authenticated users.
Refactor (with explicit boundary):
Refactor all database queries in src/lib/db/ to use prepared statements
instead of string interpolation. Do not touch src/lib/db/migrations/ —
those files should remain unchanged. After refactoring, run npm test to
confirm the test suite still passes.
Best Practices for Delegating Complex Tasks
When handing Claude Code a complex task, structure your prompt with these principles:
-
State the goal, not the steps. "Implement user search with autocomplete" is better than "create a file, then add a component, then wire it up."
-
Provide constraints. Mention what must not change, what performance requirements exist, and what patterns to follow.
-
Set a verification checkpoint. End with "run the tests," "run the type checker," or "verify the page renders correctly." This gives Claude a success criterion.
-
Scope to one concern. A single prompt should address one feature, one bug, or one refactor. Combining unrelated work increases error rates.
-
Trust the loop. Let Claude read, edit, run, and fix. Resist the urge to intervene after every step. Review the final output rather than micromanaging the process.
-
Use /clear between tasks. Context from a previous task can mislead Claude on the next one. Start clean.
Key Takeaways
- Claude Code is a full agentic loop: it reads files, edits code, runs commands, and iterates — you describe outcomes, not steps
- Use plan mode for risky or wide-ranging changes; use direct execution for well-scoped additive work
- CLAUDE.md files provide persistent project context so you do not repeat architecture and conventions in every prompt
- Hooks automate pre- and post-action workflows like linting, formatting, and testing
- Parallel agents via
/agentslet you run independent tasks concurrently for faster throughput - Keep sessions focused on a single goal — use
/clearbetween unrelated tasks to prevent context bleed - Always include a verification step: ask Claude to run tests or typecheck after making changes, not just implement and stop
- Give Claude a starting point and explicit boundaries for large multi-file changes — scope in, scope out
Discussion
Sign in to join the discussion.

