Claude Code changes the relationship between a developer and an AI assistant.
A conventional coding assistant waits for a question, produces a suggestion, and leaves the rest to you. Claude Code can inspect a repository, search through files, edit several parts of the project, run commands, execute tests, read errors, revise its implementation, and continue until the requested outcome is verified. It behaves less like autocomplete and more like a junior engineering partner operating inside your development environment.
That difference is powerful, but it also creates a new responsibility. Claude can only work as well as the environment, instructions, feedback, and verification mechanisms you give it. A poorly structured repository forces Claude to guess. An overloaded instruction file wastes context. A vague request can produce a technically valid solution that does not fit the architecture. A well prepared project, by contrast, lets Claude move quickly while remaining predictable.
This guide starts from first principles. It explains how Claude Code works, how the terminal interface differs from the VS Code extension and other IDE integrations, how to structure a repository for reliable results, how to write effective project instructions, and how to extend Claude Code with skills, hooks, subagents, plugins, and MCP servers.
The central idea is simple:
Claude Code performs best when the repository itself explains how it should be understood, changed, and verified.
Foundations: understanding Claude Code
What Claude Code actually is
Claude Code is an agentic coding environment created by Anthropic. It is available through a terminal CLI, a native VS Code extension, integrations for JetBrains IDEs, the Claude desktop application, and browser based environments.
The word agentic matters. Claude Code does not only generate text. It operates through an action loop.
When you give it a task, Claude generally performs three kinds of work:
- It gathers context by reading files, searching symbols, inspecting configuration, checking git history, and studying related tests.
- It takes action by editing files, creating new files, running commands, installing packages when permitted, or interacting with connected systems.
- It verifies the result by running tests, type checks, builds, linters, application commands, or other checks available in the project.
These phases are not always separate. Claude may read a file, make a small change, run a test, inspect the failure, search another file, and revise the implementation. This repeated cycle is the agentic loop.
You remain part of that loop. You can interrupt, redirect, add context, reject an approach, or ask Claude to explain what it is doing. The quality of the collaboration depends heavily on how clearly you define the outcome and how easily Claude can evaluate its own work.
Anthropic describes the loop in its official explanation of how Claude Code works.
Why Claude Code is different from ordinary chat
A normal chat session has limited knowledge of your actual environment. You paste snippets, describe errors, and manually apply suggestions. That workflow creates several gaps.
The assistant may not see the surrounding architecture.
The assistant may assume versions or APIs that your project does not use.
The assistant cannot usually inspect the real test output.
The assistant may suggest changes that conflict with repository conventions.
Claude Code reduces these gaps because it can work directly with the project. It can inspect the actual dependency files, find the existing implementation pattern, run the same commands as a developer, and compare its changes with the repository state.
This does not mean Claude always knows what to do. It means Claude has the tools needed to discover what to do.
The distinction is important. Claude Code is not valuable because it has perfect knowledge. It is valuable because it can investigate, act, and verify.
The terminal CLI and the VS Code extension
The CLI and the VS Code extension use the same core Claude Code capabilities, but they create different working experiences.
The right choice depends on how you think, how much visual review you need, and whether the task is interactive, automated, or spread across several terminal processes.
The Claude Code CLI
The CLI runs in a terminal from the root of a repository.
A typical start looks like this:
cd /path/to/project
claude
The CLI is the most direct and flexible interface. It is especially effective for developers who already live in a terminal, use tmux or terminal multiplexers, manage remote machines, work through SSH, or want to compose Claude with shell commands and scripts.
The CLI is usually the strongest choice for:
- Repository wide changes involving many files.
- Long debugging sessions where command output matters more than visual diffs.
- Remote development environments.
- Shell based workflows.
- Parallel sessions using git worktrees.
- Automated or non interactive execution.
- Piping input into Claude from another command.
- Running Claude inside CI, containers, or scripted processes.
The CLI also exposes the environment in a very honest way. You see commands, approvals, output, and failures in the same place. That transparency is useful when you want to understand exactly how Claude is operating.
Its main weakness is visual density. Reviewing a large multi file change in a terminal can be less comfortable than reviewing an inline diff in an editor. The CLI also requires more familiarity with terminal navigation and shell concepts.
The VS Code extension
The VS Code extension gives Claude Code a native graphical interface inside the editor. It includes inline diffs, file and line references, editable plan review, conversation history, multiple conversation tabs, and editor aware context.
Anthropic recommends the extension as the primary Claude Code experience inside VS Code. The extension bundles its own Claude Code binary for the chat panel. A separate standalone CLI installation is still required when you want to run the claude command directly in the integrated terminal.
The extension is usually the strongest choice for:
- Reviewing changes visually before accepting them.
- Referring to a selected section of code.
- Asking questions about the file currently open.
- Working through small or medium sized features interactively.
- Comparing a proposed plan with the actual editor state.
- Switching between manual editing and Claude assisted editing.
- Developers who are less comfortable in a terminal.
- Sessions where precise line level context matters.
A particularly useful feature is the ability to select code and include that selection in a prompt. This removes ambiguity. Instead of saying, “the validation function near the bottom of the file,” you can select the exact lines and ask Claude to explain, refactor, or test them.
The extension is documented in Use Claude Code in VS Code.
The practical difference
The CLI is process oriented. The editor extension is review oriented.
In the CLI, you naturally think in terms of commands, repository state, logs, branches, and automation.
In VS Code, you naturally think in terms of files, selections, visual plans, and diffs.
Neither interface is inherently more intelligent. The difference is the way context is presented and the way you supervise the work.
Many experienced users combine both.
They use the extension for focused implementation and visual review. They use the CLI for repository analysis, long running tasks, automation, worktrees, and command heavy debugging. Because both surfaces read the same repository configuration, a well prepared project works consistently in either environment.
JetBrains and other IDEs
Claude Code also supports JetBrains IDEs such as IntelliJ IDEA, PyCharm, and WebStorm. The JetBrains integration provides contextual sharing and interactive diff review, but it requires the standalone Claude Code CLI.
Other editors can still use Claude Code through an integrated terminal. This is often enough because the CLI does not depend on a specific editor.
For editors based on VS Code, the extension may also be available through the editor marketplace or the Open VSX registry. Support can vary by product, so the CLI remains the most portable option.
Installation and first launch
Anthropic currently recommends the native installation method.
For macOS, Linux, and WSL:
curl -fsSL https://claude.ai/install.sh | bash
For Windows PowerShell:
irm https://claude.ai/install.ps1 | iex
For Windows Command Prompt:
curl -fsSL https://claude.ai/install.cmd -o install.cmd && install.cmd && del install.cmd
Homebrew and WinGet installation options are also available. The native installer can update automatically, while package manager installations may require manual updates.
After installation:
cd your-project
claude
The first session asks you to authenticate. Depending on your environment, you can use a supported Claude subscription, an Anthropic Console account, or a configured third party provider.
For the VS Code extension, install “Claude Code” from the Extensions view, open a project, and launch Claude from the Spark icon, the Activity Bar, the Command Palette, or the status bar.
The current installation methods are listed in the official Claude Code overview.
The most important concept: context is a limited resource
Every Claude Code session operates inside a context window.
The context contains your messages, Claude responses, files Claude reads, command output, project instructions, tool descriptions, and other information loaded during the session. As the session grows, the context becomes crowded.
This creates a practical limit. A long conversation may contain more information than Claude can use effectively at once. Even before the hard limit is reached, performance can decline. Earlier details become less prominent. Instructions can be forgotten. The agent may repeat searches, lose architectural focus, or make inconsistent decisions.
This is why the best Claude Code workflows are not built around maximum input. They are built around relevant input.
A useful mental model is:
Every file read, command output, and instruction competes for attention.
This leads to several rules.
- Keep permanent instructions concise.
- Do not paste large logs when Claude can read the relevant file or run the command.
- Delegate broad exploration to subagents.
- Start a fresh session when the task changes substantially.
- Use
/compactwhen a productive session has become too large. - Point Claude toward the likely area instead of asking it to scan everything.
- Ask for verification in the same prompt so the session ends with evidence.
Anthropic calls context management the primary constraint in its official best practices.
Designing a project Claude can understand
The ideal project structure for Claude Code
Claude Code does not require a special application architecture. It can work with almost any repository.
However, some repository structures are much easier for an agent to understand than others.
A good structure makes five things obvious:
- Where source code lives.
- Where tests live.
- How the application is built and run.
- Which architectural boundaries must be respected.
- How a change can be verified.
The following structure is a strong general template:
project-root/
├── CLAUDE.md
├── README.md
├── package.json
├── pyproject.toml
├── Makefile
├── .gitignore
├── .env.example
├── .claude/
│ ├── settings.json
│ ├── settings.local.json
│ ├── rules/
│ │ ├── architecture.md
│ │ ├── testing.md
│ │ └── security.md
│ ├── skills/
│ │ ├── review/
│ │ │ └── SKILL.md
│ │ ├── migration/
│ │ │ └── SKILL.md
│ │ └── release/
│ │ └── SKILL.md
│ └── agents/
│ ├── code-reviewer.md
│ └── test-investigator.md
├── docs/
│ ├── architecture/
│ │ ├── overview.md
│ │ ├── data-flow.md
│ │ └── decisions/
│ ├── development/
│ │ ├── setup.md
│ │ ├── testing.md
│ │ └── debugging.md
│ └── product/
│ └── domain-glossary.md
├── scripts/
│ ├── bootstrap
│ ├── test
│ ├── lint
│ ├── typecheck
│ └── verify
├── src/
│ ├── domain/
│ ├── application/
│ ├── infrastructure/
│ └── interfaces/
├── tests/
│ ├── unit/
│ ├── integration/
│ └── fixtures/
└── examples/
└── minimal-usage/
Not every project needs every directory. The principle matters more than the exact names.
Keep the root understandable
The project root should reveal the essential commands and boundaries without requiring a deep search.
A developer, human or agent, should quickly identify:
- The primary package or build configuration.
- The main source directory.
- The test directory.
- The project instructions.
- The environment template.
- The most important documentation.
A root containing hundreds of unrelated files creates noise. Move generated output, temporary artifacts, long reports, and archival material into clear subdirectories or exclude them.
Give commands stable names
Claude works best when common operations have one canonical command.
Instead of requiring Claude to remember several framework specific invocations, provide stable wrappers such as:
./scripts/test
./scripts/lint
./scripts/typecheck
./scripts/verify
A Makefile, Taskfile, package scripts, or project specific command runner can serve the same purpose.
For example:
{
"scripts": {
"dev": "vite",
"test": "vitest run",
"lint": "eslint .",
"typecheck": "tsc --noEmit",
"verify": "npm run lint && npm run typecheck && npm test"
}
}
Stable commands improve Claude performance for two reasons.
First, they reduce ambiguity. Claude does not need to rediscover how the project is tested in every session.
Second, they improve verification. You can ask Claude to run one command that represents the project quality gate.
Separate generated files from authored files
Generated files should live in predictable locations such as dist, build, coverage, or generated.
Do not mix generated files with hand written source unless the framework requires it. Claude may waste context reading generated output, edit files that will later be overwritten, or mistake generated code for the preferred coding style.
Exclude generated directories from normal search where appropriate. In VS Code, the Claude Code extension can respect .gitignore patterns. Claude Code permission rules can also deny access to sensitive or irrelevant paths.
Make architectural boundaries visible
Claude cannot reliably obey boundaries that exist only in the mind of the original author.
If the project follows a layered architecture, make the layers visible in directory names and document their dependency rules.
For example:
src/
├── domain/
├── application/
├── infrastructure/
└── interfaces/
Then state the rule clearly:
The domain layer must not import infrastructure code.
Application services may depend on domain interfaces.
Infrastructure implements interfaces defined by the domain or application layer.
HTTP handlers must not contain business rules.
This is far more useful than saying, “follow clean architecture.”
The general rule is:
Prefer explicit local rules over abstract architectural labels.
Put tests near the behavior they verify
Claude finds tests more easily when the relationship between code and tests is predictable.
Both of these structures can work:
src/user/user-service.ts
src/user/user-service.test.ts
or:
src/user/user-service.ts
tests/user/user-service.test.ts
The important part is consistency.
When naming conventions are stable, Claude can quickly locate reference tests, copy the existing testing style, and verify new behavior.
Add small examples
An examples directory is extremely valuable when the public API is not obvious.
A short, working example often teaches Claude more effectively than a long conceptual description. It shows real imports, configuration, error handling, and expected usage.
Examples should run. Broken examples create misleading context.
Document domain language
Business software often contains words that have precise local meanings.
A term such as “account,” “workspace,” “tenant,” “member,” or “subscription” may mean something different in every company.
Create a short domain glossary:
# Domain glossary
## Workspace
A billing and data isolation boundary.
## Member
A user with access to one workspace.
## Owner
A member with billing and administrative permissions.
## Subscription
The commercial plan attached to a workspace, never directly to a user.
This prevents Claude from creating plausible but incorrect relationships.
CLAUDE.md: the operating manual for the repository
CLAUDE.md is the most important Claude Code configuration file.
Claude reads it at the beginning of a session. It should contain durable project knowledge that applies to most tasks.
A project level file can live at:
./CLAUDE.md
or:
./.claude/CLAUDE.md
You can run:
/init
to ask Claude Code to analyze the repository and create an initial version.
Anthropic recommends keeping each CLAUDE.md concise, specific, and generally under 200 lines because it consumes context in every session. See How Claude remembers your project.
What belongs in CLAUDE.md
A strong file usually includes:
- The purpose of the project.
- The most important directories.
- Canonical build, test, lint, and type check commands.
- Architectural rules.
- Coding conventions that cannot be inferred reliably.
- Required verification steps.
- Security or data handling constraints.
- A short definition of done.
- Pointers to deeper documentation.
What does not belong in CLAUDE.md
Avoid placing the following material in the main file:
- Long tutorials.
- Entire style guides.
- Rare deployment procedures.
- Personal preferences.
- Temporary task notes.
- Large API references.
- Information already obvious from standard configuration.
- Instructions that apply only to one narrow directory.
Move procedural material into skills. Move scoped rules into .claude/rules. Move private preferences into CLAUDE.local.md or user configuration.
A good CLAUDE.md example
# Project purpose
This service manages workspace billing, subscriptions, and invoices.
# Repository map
`src/domain` contains business rules and entities.
`src/application` contains use cases.
`src/infrastructure` contains database and external service adapters.
`src/http` contains request parsing and response formatting.
# Commands
Install dependencies with `npm ci`.
Run the development server with `npm run dev`.
Run unit tests with `npm test`.
Run all quality checks with `npm run verify`.
# Architecture rules
The domain layer must not import from infrastructure or HTTP code.
Business rules belong in domain entities or application services.
HTTP handlers must validate transport input, call one application service, and map the result to a response.
Database queries must remain inside repository implementations.
# Coding rules
Use existing result types for expected business failures.
Do not throw exceptions for normal validation errors.
Prefer existing utilities before adding dependencies.
New public behavior requires tests.
# Verification
Before completing a task, run the most relevant focused tests.
For changes that affect shared types or public interfaces, run `npm run verify`.
Summarize changed files, verification commands, and any remaining risk.
This works because every statement is actionable.
Use imports carefully
CLAUDE.md can import other files with the @path syntax.
For example:
See @README.md for the project overview.
Follow @docs/development/testing.md for test conventions.
Imports are useful when the referenced file is concise and relevant to most sessions.
Do not import an enormous handbook into every conversation. Imports still consume context at session start.
Use CLAUDE.local.md for private preferences
Create CLAUDE.local.md at the repository root for personal instructions that should not be committed.
Examples include:
Prefer concise explanations.
Use my local Docker profile when running integration tests.
Do not start long running development servers unless I ask.
Add the file to .gitignore.
Shared project policy belongs in CLAUDE.md. Personal workflow preferences belong in CLAUDE.local.md or user level configuration.
Scoped rules with .claude/rules
Large repositories often need instructions that apply only to certain parts of the codebase.
Putting every rule in the root CLAUDE.md creates noise. A better approach is to use .claude/rules for focused instruction files.
Example:
.claude/
└── rules/
├── frontend.md
├── database.md
├── security.md
└── testing.md
A frontend rule might explain component conventions. A database rule might define migration safety. A security rule might describe protected data and required review.
Keep each rule narrow. The name should communicate its purpose immediately.
This creates a layered instruction system:
CLAUDE.mdcontains universal project rules..claude/rulescontains scoped engineering rules.- Skills contain repeatable procedures.
- Hooks contain deterministic enforcement.
- Permissions define hard access boundaries.
Understanding these layers prevents a common mistake: trying to solve every problem with more text in CLAUDE.md.
Extending Claude Code
Skills: reusable procedures that load only when needed
A skill is a reusable workflow stored in a SKILL.md file.
Skills are ideal for repeated procedures such as:
- Reviewing a pull request.
- Creating a database migration.
- Preparing a release.
- Investigating an incident.
- Updating an API client.
- Generating a changelog.
- Running a project specific security review.
A project skill lives under:
.claude/skills/<skill-name>/SKILL.md
For example:
.claude/skills/migration/SKILL.md
The major advantage is contextual efficiency. The body of a skill loads when the skill is used, not at the beginning of every session.
This makes skills the correct destination for instructions that are important but not universal.
The official documentation explains skills in Extend Claude with skills.
A migration skill example
---
name: migration
description: Create and verify a safe database migration for this project.
---
# Goal
Create a reversible migration that follows the repository conventions.
# Procedure
1. Inspect the current schema and recent migrations.
2. Identify compatibility risks for deployed application versions.
3. Prefer additive changes before destructive changes.
4. Create the migration using the project migration tool.
5. Update affected models and repository code.
6. Add or update integration tests.
7. Run the migration against the development database.
8. Run the focused test suite.
9. Explain rollout and rollback considerations.
# Constraints
Never remove a production column in the same release that stops writing it.
Never add a non nullable column without a safe default or staged rollout.
Do not modify an already deployed migration.
The skill can then be invoked as:
/migration add a nullable external_reference field to invoices
When to create a skill
Create a skill when you notice yourself repeating the same detailed prompt.
A useful test is:
Would another developer benefit from running this exact procedure next month?
If yes, it probably deserves a skill.
Keep skills outcome focused
A weak skill says, “Be an expert reviewer.”
A strong skill defines what to inspect, what evidence to collect, what risks to prioritize, and what output to produce.
Skills should reduce uncertainty, not add personality.
Hooks: deterministic automation around Claude actions
Instructions influence Claude. Hooks execute commands.
This difference is essential.
A sentence in CLAUDE.md such as “format files after editing” is a request. Claude may follow it, forget it, or decide it is not necessary.
A hook that runs a formatter after an edit is deterministic.
Hooks can respond to lifecycle events before or after tool use, when Claude needs input, when a session ends, and at other defined points.
Common uses include:
- Formatting files after edits.
- Blocking changes to protected paths.
- Running a linter after code modifications.
- Adding notifications when Claude needs attention.
- Recording an audit trail.
- Injecting context after compaction.
- Validating commands before execution.
- Preventing accidental access to sensitive files.
Hooks are powerful because they run local commands. They must be written with the same care as any automation that handles untrusted input.
Validate inputs, quote shell variables, use absolute paths, prevent path traversal, and exclude secrets. Anthropic documents these concerns in the Hooks reference and the Hooks guide.
Instructions versus hooks
Use an instruction when judgment is required.
Use a hook when enforcement is required.
For example:
Prefer focused tests before the full suite.
This is an instruction because Claude must choose the relevant tests.
By contrast, automatically formatting every edited TypeScript file is a good hook because the action is mechanical and predictable.
Subagents: protect the main conversation from noise
A subagent is a specialized Claude worker with its own context window, instructions, and tool access.
The main benefit is context isolation.
Imagine asking Claude to investigate a complicated authentication system. The investigation may require reading dozens of files and command outputs. If all of that enters the main conversation, the session becomes crowded before implementation begins.
A subagent can perform the investigation separately and return a concise summary.
Good subagent tasks include:
- Mapping a large subsystem.
- Reading extensive logs.
- Comparing several implementation options.
- Reviewing a change independently.
- Investigating test failures.
- Searching documentation.
- Examining security implications.
- Producing a focused architectural summary.
Project subagents live in:
.claude/agents/
User level subagents live in:
~/.claude/agents/
Anthropic explains the model in Create custom subagents.
A code reviewer subagent
---
name: code-reviewer
description: Review completed changes for correctness, security, maintainability, and missing tests.
tools: Read, Grep, Glob, Bash
---
Review the current git diff.
Focus on defects that can change behavior, expose data, break compatibility, or leave important paths untested.
Read surrounding code before judging a change.
Run focused read only checks when useful.
Report findings in severity order.
For every finding, include the file, location, concrete failure scenario, and recommended correction.
Do not edit files.
This subagent is useful because it provides an independent pass without filling the implementation conversation with review exploration.
When not to use a subagent
Do not delegate every small task.
Subagents add coordination and token cost. A simple local change is usually better handled in the main conversation.
Use a subagent when its work would create substantial temporary context or when an independent perspective is genuinely useful.
Plugins: packaging skills, agents, hooks, MCP, and language intelligence
A plugin is a distributable package that can bundle several Claude Code extensions.
A plugin may contain:
- Skills.
- Subagents.
- Hooks.
- MCP server configuration.
- Language Server Protocol integration.
- Other supporting components.
Plugins are useful when the same setup should be reused across repositories or distributed to a team.
Claude Code includes access to an official Anthropic marketplace. Open the plugin manager with:
/plugin
A plugin can be installed with:
/plugin install plugin-name@marketplace-name
For example, the official documentation uses:
/plugin install github@claude-plugins-official
The official marketplace also includes language intelligence plugins for languages such as Python, TypeScript, Go, Rust, Java, Kotlin, Swift, and others. These plugins connect Claude Code to language servers so it can use definitions, references, and type diagnostics more directly.
Browse plugin details before installing. A plugin can add commands, hooks, external connections, and tool access. Treat it as executable development tooling, not as a harmless prompt template.
The official plugin workflow is documented in Discover and install prebuilt plugins.
How to evaluate a plugin
Before installation, inspect:
- The publisher and repository.
- The components it adds.
- The tools and systems it can access.
- Its update policy.
- Its dependencies.
- Whether the workflow is better implemented locally as a small skill.
- Whether the plugin is necessary for every project or only one repository.
The best plugin collection is not the largest one. It is the smallest collection that removes repeated friction.
MCP: connect Claude Code to external systems
MCP stands for Model Context Protocol.
An MCP server gives Claude Code structured access to external tools, databases, APIs, and services. Instead of copying information from another system into the chat, Claude can query that system through an approved integration.
Common examples include:
- GitHub.
- Jira or other issue trackers.
- Sentry and observability tools.
- Databases.
- Slack.
- Figma.
- Internal documentation.
- Custom company services.
MCP is most valuable when the missing context lives outside the repository.
For example, a task may require Claude to read a ticket, inspect an error in Sentry, modify code, run tests, and create a pull request. MCP can connect those steps into one workflow.
Do not connect every available system. Each server expands the tool surface, consumes some context, and creates another security boundary.
Add an MCP server when you repeatedly copy information from the same external system into Claude Code.
The complete integration model is described in Connect Claude Code to tools via MCP.
Permissions, safety, and operational control
Permissions and safety
Claude Code can read files, write files, and execute commands. That power requires explicit boundaries.
Claude Code uses a permission system with allow, ask, and deny rules.
Allow rules permit a matching action.
Ask rules require confirmation.
Deny rules block the action.
The permission interface is available through:
/permissions
Project permission settings can be committed so every developer receives the same baseline. Personal overrides can remain local.
A good default is conservative.
Allow routine development commands that are safe and reversible.
Require confirmation for network operations, deployments, package publication, destructive database changes, and git pushes.
Deny access to secrets and unrelated directories.
Protect sensitive files
A project can deny reads from secret paths in .claude/settings.json.
{
"permissions": {
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)",
"Read(./config/credentials.json)"
]
}
}
This is stronger than writing “do not read secrets” in CLAUDE.md. Permission rules are enforced by the Claude Code application, not merely interpreted by the model.
Use plan mode for risky changes
Plan mode lets Claude inspect the repository and propose an implementation without modifying source files.
It is useful for:
- Large refactors.
- Database migrations.
- Security sensitive changes.
- Unfamiliar repositories.
- Tasks with ambiguous scope.
- Changes that cross several architectural boundaries.
Review the plan before allowing implementation.
A practical workflow is:
Study the billing flow and propose a plan for adding annual subscriptions.
Do not edit files yet.
Identify affected modules, schema changes, compatibility risks, tests, and rollout steps.
After reviewing the plan:
Implement the approved plan.
Run focused tests after each logical stage.
Finish with the full verification command.
Use sandboxing for stronger isolation
Claude Code can run shell commands inside a sandbox that limits filesystem writes and network access.
Open the sandbox interface with:
/sandbox
Sandboxing is particularly valuable when:
- You reduce routine permission prompts.
- You work with an unfamiliar repository.
- Claude may run third party tools.
- The task involves generated or downloaded content.
- You run autonomous sessions.
A sandbox is not a substitute for review. It is an additional boundary.
Anthropic documents sandbox setup and behavior in Configure the sandboxed Bash tool.
Avoid unrestricted permission bypass
Claude Code provides modes that can reduce or skip approval prompts. These modes can be useful inside isolated containers or virtual machines.
Do not use unrestricted bypass on a normal workstation containing credentials, personal files, or production access.
Convenience is not worth removing the last meaningful boundary between an agent mistake and your system.
Prompting and reliable engineering workflows
How to write prompts that produce better engineering work
Claude Code prompts should describe an outcome, relevant context, constraints, and verification.
A strong prompt answers four questions.
- What should change?
- Where should Claude begin?
- What must remain true?
- How will success be checked?
Weak prompt
Fix authentication.
This is too broad. Claude must guess the symptom, expected behavior, scope, and completion criteria.
Better prompt
Users with an expired access token are being logged out even when their refresh token is valid.
Start by tracing the refresh flow from the HTTP middleware to the token service.
Find the root cause before editing.
Preserve the current behavior for revoked refresh tokens.
Add a regression test that fails on the current implementation.
Implement the smallest safe fix, run the focused authentication tests, then run the type checker.
Summarize the root cause and the evidence that the fix works.
This prompt gives Claude a path and a definition of done without prescribing the implementation.
Tell Claude where to look
Specific references reduce search cost.
Useful context includes:
Follow the pattern in `src/billing/create-subscription.ts`.
The failing test is `tests/auth/token-refresh.test.ts`.
The public interface must remain compatible with `packages/client`.
Use the existing error type in `src/domain/errors.ts`.
This is better than pasting entire files.
Ask Claude to investigate before editing
For complex tasks, separate diagnosis from implementation.
Investigate the failure first.
Do not modify files until you can explain the root cause, affected code path, and proposed fix.
This prevents premature edits based on the first plausible hypothesis.
Give Claude a verification method
Anthropic repeatedly emphasizes this practice.
Ask Claude to run the application, tests, type checker, linter, migration, benchmark, or comparison required to prove the result.
Examples:
Implement the endpoint and verify it with an integration test.
Update the parser, run the existing fixture suite, and add a fixture for the reported edge case.
Change the layout and use the running application to confirm the mobile and desktop states.
A task without verification is a request for code. A task with verification is a request for an engineering outcome.
A reliable workflow for feature development
The following sequence works well for medium and large changes.
Phase one: understand
Ask Claude to inspect the relevant architecture, related code, tests, and constraints.
Study how invoice creation works.
Identify the entry points, domain rules, persistence layer, background jobs, and existing tests.
Return a concise architecture map.
Do not edit files.
Phase two: plan
Ask for a concrete plan.
Plan the addition of invoice cancellation.
The plan must cover domain behavior, authorization, persistence, API changes, events, tests, backward compatibility, and rollout risk.
Review the plan. Correct wrong assumptions before code exists.
Phase three: implement in logical steps
Implement the approved plan.
Work in small logical stages.
After each stage, run the most relevant focused test.
Do not change unrelated formatting or public APIs.
Phase four: verify broadly
Run the full project verification command.
Inspect the final git diff for accidental changes, missing tests, and inconsistent naming.
Fix any issue you find.
Phase five: independent review
Use a subagent or a fresh session.
Review the current diff as an independent senior engineer.
Look for correctness defects, security issues, compatibility breaks, race conditions, and missing tests.
Do not edit files.
An independent review is valuable because the implementation conversation may contain assumptions that bias the same agent toward its own design.
A reliable workflow for debugging
Debugging quality depends on hypothesis control.
A weak debugging session becomes a sequence of random edits. A strong session creates evidence.
Use this structure:
Reproduce the failure before editing.
Trace the failing path and identify the earliest incorrect state.
List the leading hypotheses and the evidence for each.
Add temporary diagnostics only when necessary.
Implement the smallest fix that addresses the demonstrated root cause.
Add a regression test.
Remove temporary diagnostics.
Run the focused test and the relevant wider suite.
Ask Claude to distinguish root cause from symptom.
For intermittent problems, ask it to inspect concurrency, time, retries, state leakage, and nondeterministic test setup.
For performance problems, require measurement before optimization.
Measure the current behavior first.
Identify the dominant cost.
Make one targeted change.
Run the same measurement again and report the comparison.
A reliable workflow for refactoring
Refactoring should preserve behavior.
Claude can perform broad mechanical changes quickly, but broad speed can hide subtle regressions.
A strong prompt includes invariants:
Refactor the notification dispatch code to remove duplication.
Preserve public interfaces, event ordering, retry behavior, logging fields, and error semantics.
First identify the existing behavioral contract from tests and callers.
Make the change in small stages.
Run focused tests after each stage.
Finish with the full verification command and a diff review.
For large refactors, use git worktrees or small commits so each stage remains reversible.
Git worktrees and parallel sessions
Claude Code can run several sessions in parallel, but simultaneous edits in one working directory can collide.
Git worktrees solve this problem. Each worktree has its own checkout and branch.
Claude Code supports worktree based workflows, including commands such as:
claude --worktree feature-auth
A practical pattern is:
- One worktree for the feature.
- One worktree for an independent review or experiment.
- One worktree for a separate bug fix.
Keep tasks independent. Parallelism is useful when work streams do not need constant coordination.
Do not start many agents merely because you can. Parallel sessions increase cost, review load, and integration complexity.
Use parallel work when the tasks are separable and the expected speed gain exceeds the coordination cost.
Managing long sessions
Long sessions require active maintenance.
Correct Claude early
Do not allow a wrong assumption to survive for twenty actions.
Interrupt as soon as you see drift.
Stop.
The subscription belongs to the workspace, not the user.
Reevaluate the plan and identify every place where that assumption affected your reasoning.
Early correction is cheaper than repairing a large implementation.
Use /compact
/compact summarizes the conversation and frees context space.
Use it after a meaningful phase, such as investigation, planning, or a completed implementation stage.
Before compacting, ask Claude to record durable project knowledge in the appropriate file when needed. Do not rely on conversation history for rules that should survive future sessions.
Start a fresh session when the objective changes
A fresh session is often better than continuing a crowded conversation.
Start again when:
- The original task is complete.
- The new task concerns a different subsystem.
- The session contains extensive obsolete logs.
- Claude repeatedly returns to a discarded approach.
- The conversation has become difficult to summarize clearly.
Resume an existing session when the same objective continues and the earlier decisions still matter.
Interface specific techniques
CLI techniques that save time
The CLI becomes especially powerful when combined with shell workflows.
Start with a direct prompt
claude "inspect the current diff, run focused tests, and identify defects"
This is useful for a bounded task that does not require a long conversation.
Use non interactive output in scripts
Claude Code supports command based execution suitable for scripting and automation. Consult the current CLI reference because flags and output formats can evolve.
A common pattern is to ask Claude to produce structured output for another tool. Keep automated prompts narrow and deterministic. Always define the expected result and failure behavior.
Pipe relevant input
Instead of copying output manually, pipe it when appropriate.
git diff | claude "review this diff for correctness and missing tests"
Avoid piping enormous unfiltered logs. Extract the relevant section first.
Use files for very large input
Very large pasted content can be fragile, especially in integrated terminals. Save large logs or specifications to a file and ask Claude to read that file.
command-that-produces-output > /tmp/diagnostic.log
claude "analyze /tmp/diagnostic.log and identify the likely root cause"
Keep one terminal for observation
For complex application debugging, keep a second terminal open for logs, database inspection, or manual testing.
Claude can run commands, but independent observation helps you catch environmental assumptions and long running process issues.
VS Code techniques that improve precision
Select exact lines
Use editor selections when the question concerns a local behavior.
A precise selection reduces unnecessary file reading and makes the prompt easier to understand.
Review plans before edits
For broad tasks, ask Claude to create a plan and inspect it in the extension before accepting implementation.
Look for:
- Missing affected modules.
- Incorrect architecture assumptions.
- Unnecessary dependency changes.
- Missing migration or compatibility steps.
- Weak verification.
Editing a plan is cheaper than editing a patch.
Use inline diffs as a teaching tool
Do not only accept or reject a complete change.
Study the diff and tell Claude what is wrong with the approach.
This duplicates the validation rule already implemented in the domain object.
Rework the change so the HTTP layer delegates to the existing domain behavior.
That correction helps the current session and may reveal a missing project rule that belongs in CLAUDE.md.
Open separate conversations for separate objectives
The extension can open multiple conversations in separate tabs.
Use separate conversations for:
- Feature implementation.
- Independent review.
- Documentation.
- Unrelated bug investigation.
This prevents context contamination.
Include terminal output selectively
When a terminal command fails, include the relevant output in the prompt. Do not include thousands of irrelevant lines.
The ideal context is the command, the error, a small amount of surrounding output, and the expected behavior.
Common mistakes and professional adoption
Common failure patterns
The giant CLAUDE.md
A huge instruction file feels comprehensive but creates permanent context pressure.
Symptoms include slow starts, ignored details, contradictory rules, and poor prioritization.
Fix it by moving procedures into skills, scoped guidance into rules, and private preferences into local files.
Vague completion criteria
“Improve this code” gives Claude no objective stopping point.
Define observable success.
Reduce duplicate database queries in the order endpoint without changing the response schema.
Add a query count test and keep the count at or below three.
No verification command
Claude may stop after producing plausible code.
Always specify how to check the result.
Asking for code before understanding
Premature implementation encourages local fixes that miss the real architecture.
Ask for investigation and a plan first when the task crosses boundaries.
Letting Claude edit unrelated files
Broad formatting, automatic dependency updates, and generated file changes can obscure the real patch.
State scope explicitly.
Do not modify files outside `src/billing` and `tests/billing` without explaining why first.
Installing too many extensions
Every plugin, MCP server, hook, and rule increases complexity.
Add one extension when it solves a repeated problem. Test it. Document why it exists. Remove it when it no longer provides value.
Treating Claude output as authority
Claude is an engineering tool, not an oracle.
Review security sensitive logic, migrations, access control, financial calculations, concurrency, and infrastructure changes carefully.
The purpose of tests and independent review is not ceremonial. It is to catch confident mistakes.
A recommended .claude setup for a professional repository
A balanced configuration might look like this:
.claude/
├── settings.json
├── rules/
│ ├── architecture.md
│ ├── testing.md
│ └── security.md
├── skills/
│ ├── review/
│ │ └── SKILL.md
│ ├── migration/
│ │ └── SKILL.md
│ └── release/
│ └── SKILL.md
└── agents/
├── code-reviewer.md
└── investigator.md
The roles are distinct.
settings.json defines permissions, shared plugins, and stable tool configuration.
rules explains scoped constraints.
skills defines repeatable procedures.
agents defines specialized workers.
The root CLAUDE.md remains short and universal.
This separation makes the system easier to maintain and easier for new developers to understand.
A maturity model for adopting Claude Code
Teams often adopt Claude Code in stages.
Stage one: assisted exploration
Use Claude to explain code, trace behavior, and identify relevant files.
Keep edits manual or small.
The goal is trust through observation.
Stage two: bounded implementation
Give Claude focused tasks with clear tests and limited scope.
Review every diff.
The goal is to learn which prompts and repository conventions produce reliable work.
Stage three: repository configuration
Add CLAUDE.md, stable verification commands, permission rules, and a small set of skills.
The goal is consistency across sessions and team members.
Stage four: specialized automation
Add hooks, subagents, MCP integrations, and selected plugins.
The goal is to remove repeated coordination work.
Stage five: parallel and autonomous workflows
Use worktrees, CI integration, sandboxed autonomous sessions, and independent reviews.
The goal is scale without losing control.
Do not jump directly to the final stage. Autonomy is most useful after the project has clear boundaries and reliable verification.
The ideal daily workflow
A practical day with Claude Code might look like this:
- Open the repository and update the branch.
- Start Claude in the CLI or VS Code.
- Ask for a concise map of the relevant subsystem.
- Clarify the desired outcome and constraints.
- Use plan mode for anything broad or risky.
- Correct assumptions before implementation.
- Let Claude implement in small logical stages.
- Require focused verification after each stage.
- Run the full project quality gate.
- Review the final diff manually.
- Run an independent Claude review in a fresh session or subagent.
- Commit only after the evidence is convincing.
The workflow is not slower than asking Claude to code immediately. It is usually faster because it prevents rework.
Final principles
Final principles
Claude Code is most effective when you treat it as an engineering system rather than a chat window.
A strong project has explicit boundaries, canonical commands, concise instructions, reliable tests, and deterministic safeguards.
A strong prompt gives Claude an outcome, context, constraints, and a verification method.
A strong session protects context by delegating noisy exploration, correcting drift early, and starting fresh when the objective changes.
A strong extension setup remains small. Skills capture procedures. Hooks enforce mechanics. Subagents isolate research. Plugins package reusable capabilities. MCP connects external systems. Permissions and sandboxing limit risk.
The CLI and the VS Code extension are not competitors. They are two supervision styles for the same agentic workflow. The CLI excels at command driven work, remote environments, automation, and parallel repository operations. The VS Code extension excels at visual review, precise selections, plan editing, and interactive implementation.
The best interface is the one that makes the current task easiest to observe and verify.
The best repository is the one that makes the correct path obvious.
And the best Claude Code workflow is not the one that produces the most code. It is the one that produces the clearest evidence that the right code was created.
Official references
- Claude Code overview
- How Claude Code works
- Best practices for Claude Code
- Common workflows
- Use Claude Code in VS Code
- How Claude remembers your project
- Extend Claude with skills
- Create custom subagents
- Hooks reference
- Connect Claude Code to tools via MCP
- Configure permissions
- Configure the sandboxed Bash tool
- Discover and install prebuilt plugins
- Claude Code CLI reference