How I Use Claude Code in Real Development Projects

I don’t use Claude Code as a replacement for knowing how to build software. I find it much more useful as a tool that can sit inside a real codebase, read the same files I’m working with, run commands, make changes and help me move through repetitive development work faster. That distinction matters. If I…

claude-code-ai
guide.md READY

I don’t use Claude Code as a replacement for knowing how to build software.

I find it much more useful as a tool that can sit inside a real codebase, read the same files I’m working with, run commands, make changes and help me move through repetitive development work faster.

That distinction matters.

If I ask an AI coding tool to “build the whole feature” with very little context, I can get a lot of code very quickly. That doesn’t automatically mean I get the architecture, edge cases or implementation I actually wanted.

My experience with Claude Code is better when I treat it less like an automatic code generator and more like another developer working inside the repository:

  • give it enough project context
  • ask it to understand the problem before editing
  • keep changes reasonably focused
  • review the diff
  • run the tests
  • make the final engineering decision myself

This guide shows how I approach that workflow, where Claude Code genuinely helps me, and where I still don’t trust an AI agent blindly.

What Claude Code Actually Is

Claude Code is Anthropic’s agentic coding tool that works directly with a development environment.

Instead of only generating a code snippet in a chat window, it can work with the files and tools available to it inside a project.

That makes workflows such as these possible:

Read existing code
       |
       v
Understand architecture
       |
       v
Find related files
       |
       v
Plan a change
       |
       v
Edit code
       |
       v
Run tests / lint / build
       |
       v
Review the result

The important part for me is not that Claude can write code.

Plenty of AI tools can write code.

The useful part is that Claude Code can work with the surrounding repository and development tools instead of answering every question without project context.

You can read Anthropic’s current overview in the official Claude Code documentation.

Installing Claude Code Today

The installation process has changed since the original version of this article.

Anthropic currently recommends the native installer.

macOS, Linux or WSL

curl -fsSL https://claude.ai/install.sh | bash

Windows PowerShell

irm https://claude.ai/install.ps1 | iex

Homebrew and WinGet are also supported installation options.

The npm package still exists, but I would follow Anthropic’s current installation recommendation rather than copying an older npm-based tutorial without checking the latest documentation.

See the Claude Code installation documentation for the current platform-specific options.

Once it is installed, I normally open the project directory first:

cd my-project

claude

Starting it from the correct project directory sounds obvious, but it establishes an important boundary: this is the repository I want Claude to understand and work with.

My Original Claude Code Setup Video

I recorded this walkthrough when I first started covering Claude Code. The interface and installation options continue to evolve, so I recommend using the current documentation for exact installation commands, but the video is still useful for seeing the basic terminal workflow.

The First Thing I Want Claude to Do Is Read

One habit that improves my results is not asking for a big code change immediately.

If I’m working in an unfamiliar part of a repository, I first want Claude to understand what is already there.

For example:

Read the authentication module and explain:

1. how login currently works
2. where tokens are generated
3. where tokens are validated
4. how refresh tokens are stored
5. which files I should understand before changing anything

Do not modify files yet.

That last sentence is useful.

I want exploration and implementation to be separate steps when the task is complicated enough to deserve it.

If Claude misunderstands the architecture during the reading phase, correcting that misunderstanding is much cheaper than correcting twenty edited files afterward.

I Prefer Plan First, Edit Second

For a small typo, I don’t need a design document.

For a feature touching authentication, payments, caching, database behaviour or several modules, I usually want a plan before code.

A prompt might look like this:

We need to add refresh-token rotation.

Before changing code:

- inspect the current authentication flow
- identify the files that need changes
- explain the database changes
- explain how reused refresh tokens should be handled
- identify possible backwards-compatibility issues
- propose an implementation plan

Do not implement yet.

Now I have something concrete to review.

I may agree with five steps and reject the sixth.

That is much closer to the way I want to work with an AI agent: discuss the implementation first, then let it help execute an agreed direction.

CLAUDE.md Is One of the Most Useful Features

I don’t want to repeat the same project rules every time I start a new session.

That is where CLAUDE.md becomes useful.

It is a Markdown file containing persistent instructions and project information Claude should know when working in the repository.

A simple example:

# Project

This is a Node.js + TypeScript API.

## Commands

Install:
npm ci

Development:
npm run dev

Tests:
npm test

Type check:
npm run typecheck

## Architecture

- Keep controllers thin.
- Business logic belongs in services.
- Database access belongs in repositories.
- Validate request data at the API boundary.
- Do not access another module's database tables directly.

## Code style

- Use async/await.
- Avoid any unless there is a documented reason.
- Reuse existing error classes.
- Do not introduce a dependency if the platform already provides the required feature.

## Before finishing

Run:
npm run typecheck
npm test

This is much more useful than writing something vague such as:

Write clean production-quality code.

What does “clean” mean in this repository?

Where does validation belong?

Which test command should run?

The more concrete the instruction, the more useful it becomes.

Anthropic’s current memory documentation recommends using CLAUDE.md for things such as coding standards, project architecture and common workflows. Claude Code also has an auto-memory system for learnings it discovers across sessions. You can read more in the official memory documentation.

Don’t Turn CLAUDE.md into a Book

There is a temptation to put every possible instruction into one giant file.

I avoid that.

If Claude should remember something for practically every task, it belongs there.

If a rule only matters for one unusual migration that happens once per year, it probably doesn’t need to consume project context every session.

I would rather have a concise file with twenty useful rules than 500 lines that nobody—human or AI—can quickly understand.

How I Use Claude Code to Understand an Existing Codebase

This is one of the use cases I value most.

When I return to a feature I haven’t touched for a while, I can ask questions at a higher level than a normal text search.

For example:

Trace what happens when POST /orders is called.

Start at the route and follow the request through:

- validation
- controller
- service
- database
- payment handling
- event publishing

Show the important file paths and point out where errors are converted into HTTP responses.

This doesn’t replace reading the important files myself.

It gives me a map of where I should look.

I find that distinction useful. AI is very good at reducing the time spent searching for the starting point.

Debugging Is Better When I Give Claude Evidence

A weak debugging prompt looks like this:

The API is not working. Fix it.

A much better debugging request includes what I already know.

POST /checkout intermittently returns 500.

What I know:

- it happens only when the Stripe request takes more than a few seconds
- normal requests succeed
- the error started after the retry logic was added
- the relevant logs are in logs/checkout.log

Investigate the root cause first.

Do not modify anything until you can explain why the failure occurs.

Now Claude has observations instead of being asked to guess from nothing.

I use the same approach when debugging:

  • database errors
  • failed tests
  • TypeScript errors
  • WordPress PHP warnings
  • build failures
  • API timeouts

The quality of the investigation usually improves when I provide evidence and explicitly ask for the cause before the patch.

Refactoring: Ask for Behaviour Preservation

“Refactor this file” is another prompt I try not to use by itself.

A refactor needs boundaries.

Refactor the order service.

Goals:

- reduce duplicated validation
- extract payment-specific logic
- make the createOrder method easier to test

Constraints:

- do not change the public API
- do not change database schema
- preserve current error codes
- keep existing tests passing
- do not introduce new dependencies

First explain the refactoring plan.

That tells Claude what “better” means for this particular task.

Otherwise an AI tool can produce a technically tidy refactor that changes something I cared about preserving.

I Ask Claude to Use Existing Patterns Before Inventing New Ones

This makes a noticeable difference in larger repositories.

If I ask Claude to add an endpoint, I don’t necessarily want it inventing a brand-new validation style, response format and directory structure.

I might say:

Add an endpoint for updating a customer's email.

Before implementing:

1. find two similar update endpoints in this project
2. follow the same controller/service/repository pattern
3. reuse the existing validation approach
4. reuse the existing error response format
5. do not introduce a new architectural pattern

That simple instruction often produces code that looks like it belongs in the repository rather than code copied from an unrelated tutorial.

Tests Are Part of the Prompt, Not an Afterthought

I don’t want the task to end when the source file has been edited.

For a feature, I normally make verification part of the request.

Implement the change.

After implementation:

- add or update the relevant tests
- run the focused tests first
- run type checking
- run lint
- show me any failing command
- do not silently change unrelated tests to make them pass

The final instruction is important.

A failing test may indicate that the implementation is wrong.

I don’t want the AI to automatically “fix” the test without establishing whether the test or the implementation is actually incorrect.

I Still Review the Git Diff

Successful tests are not enough for me.

I still want to see what changed.

git status

git diff

Things I look for include:

  • files that should not have changed
  • debugging code left behind
  • unnecessary dependencies
  • removed validation
  • silent behaviour changes
  • overly broad refactoring
  • secrets or local configuration accidentally added

An AI agent can make five correct edits and one very questionable edit in the same task.

The fact that most of the diff looks good is not a reason to stop reviewing it.

Claude Code Permissions Matter

Claude Code can do more than read files. Depending on the permissions you give it, it can edit files and execute commands.

I treat that as a useful capability, but also as a security boundary.

When Claude asks to run something, I want to understand what that command does before allowing it.

This matters particularly around commands such as:

rm
git reset
git clean
database migrations
deployment scripts
cloud CLIs
production database commands

Claude Code provides permission controls specifically because an agent capable of taking actions needs stronger boundaries than a normal chat interface.

Anthropic’s security documentation covers permissions, prompt-injection risks and recommendations for sensitive repositories.

Why I Avoid Bypassing Permissions Casually

The CLI supports an option called:

--dangerously-skip-permissions

The name is not subtle.

I would not make bypassing permissions my default way of working on a normal development machine.

There are controlled automation environments where reduced prompting can make sense, but that should be an intentional security decision, ideally inside an environment where the process cannot damage unrelated files or infrastructure.

For ordinary development, a few permission confirmations are a reasonable price for knowing what an agent is about to execute.

Using Claude Code from the Command Line Without an Interactive Session

Claude Code is also scriptable.

The -p option runs a prompt and exits:

claude -p "Explain the purpose of this repository"

You can also pipe content into it:

cat error.log | claude -p "Summarize the likely root causes"

And structured output can be useful when another script needs to consume the result:

claude -p \
  --output-format json \
  "Review the current git diff"

The current options are documented in Anthropic’s Claude Code CLI reference.

Continue and Resume Save Time

Not every task is finished in one sitting.

Claude Code can continue the most recent conversation for the project:

claude -c

Sessions can also be resumed rather than rebuilding all the task context from scratch.

I find that useful for longer work where the previous discussion already contains architectural decisions I don’t want to explain again.

MCP Makes Claude Code More Useful Outside the Repository

A codebase isn’t always the only source of information needed to complete a development task.

The issue may live in Jira.

The error may be in a monitoring platform.

The schema may be in a database tool.

The documentation may live somewhere else entirely.

Claude Code supports the Model Context Protocol (MCP) for connecting external tools and data sources.

Claude Code
    |
    +---- repository
    |
    +---- MCP ---- issue tracker
    |
    +---- MCP ---- documentation
    |
    +---- MCP ---- database
    |
    +---- MCP ---- monitoring tools

Anthropic’s current documentation recommends HTTP for remote MCP servers and also supports local stdio servers.

You can inspect configured servers using commands such as:

claude mcp list

claude mcp get server-name

See the official Claude Code MCP guide for the current configuration options.

I also have a separate step-by-step guide on integrating an MCP server with Claude Code.

Be More Careful When MCP Can Reach Real Systems

MCP is useful precisely because it can give Claude access to things outside the local repository.

That is also why I don’t connect random MCP servers to sensitive systems without understanding what they can do.

If an MCP server can query a production database, create issues, modify cloud resources or interact with another service, the permissions of that integration matter.

I prefer the same rule I would use for any software integration:

Give it the minimum access it actually needs.

Read-only database access is safer than write access if the task only requires analysis.

A scoped API token is better than an administrator token just because it is easier to configure.

Subagents Help Keep Side Tasks Out of the Main Context

Another useful Claude Code feature is subagents.

A subagent gets its own context and can handle a focused task before returning the important result to the main session.

For example, I may want one task to investigate tests without filling the main conversation with every test file and search result.

Main task
   |
   +---- investigate architecture
   |
   +---- test-review subagent
   |        |
   |        +-- inspect tests
   |        +-- find missing cases
   |        +-- return summary
   |
   +---- continue implementation

Claude Code includes built-in agents for things such as exploration and planning, and it also allows custom agents to be defined for repeated workflows.

A project-level custom subagent can live under:

.claude/agents/

For example:

---
name: api-reviewer
description: Reviews API changes for correctness and compatibility
tools: Read, Glob, Grep
model: sonnet
---

Review API changes.

Focus on:

- validation
- backwards compatibility
- error handling
- authorization
- database impact

Do not modify files.

That is much more interesting to me than creating ten agents just because “multi-agent” sounds advanced.

I use specialization when it makes the task clearer.

The current feature is documented in the Claude Code subagent guide.

Hooks Are Useful When a Rule Should Be Deterministic

There is an important difference between asking Claude to remember to do something and making the environment do it automatically.

Suppose I want formatting to run every time files are changed.

I could repeatedly tell the AI:

Remember to format the files after editing.

Or I can use a hook for a workflow that should happen predictably.

Claude Code hooks can run at specific lifecycle events for use cases such as:

  • formatting code after edits
  • blocking protected-file changes
  • sending notifications
  • validating commands
  • adding project context at session start

That makes sense to me because deterministic project rules are better enforced deterministically than left entirely to a model remembering a sentence in a prompt.

The current options are documented in Anthropic’s Claude Code hooks guide.

Where Claude Code Saves Me the Most Time

I don’t measure the value by how many lines of code the tool generates.

Generating 1,000 lines that I don’t understand is not a productivity improvement.

The places where I think tools like Claude Code are most useful are usually less dramatic:

  • finding where an unfamiliar feature is implemented
  • following a request through several backend layers
  • explaining code before changing it
  • generating repetitive tests
  • applying an established pattern to another module
  • investigating logs and errors
  • updating several related files consistently
  • checking a diff for obvious problems
  • writing migrations or scripts that I then review carefully
  • explaining an unfamiliar library or legacy implementation

These are tasks where understanding context and reducing repetitive navigation can save meaningful development time.

Where I Don’t Give Claude Code Full Control

There are also areas where I increase my level of review rather than reducing it.

Examples include:

  • authentication and authorization
  • payment processing
  • database migrations that can destroy data
  • production infrastructure
  • encryption and security-sensitive code
  • permission changes
  • complex concurrency
  • large architectural changes

Claude can still help with those tasks.

It simply doesn’t change who is responsible for verifying them.

Claude Code Can Still Be Wrong

This should be obvious, but it’s worth saying because agentic coding can make incorrect output look surprisingly convincing.

Claude may:

  • misunderstand an undocumented business rule
  • assume an API behaves differently than it actually does
  • use an outdated library pattern
  • miss an indirect side effect
  • write a test that validates the wrong behaviour
  • solve the visible symptom rather than the root cause
  • make a broader change than the task required

The dangerous case isn’t obviously broken code.

Obviously broken code gets noticed.

The dangerous case is code that looks completely reasonable but encodes the wrong assumption.

The Prompt Matters, but Context Matters More

I don’t spend much time trying to discover one magical prompt.

I care more about giving Claude the information a developer would need.

Compare these two requests.

Weak

Add authentication.

Better

Add JWT authentication to the existing API.

Before implementing:

- inspect the current user module
- reuse our existing validation style
- passwords are already hashed with Argon2
- access tokens should expire after 15 minutes
- refresh tokens must be revocable
- do not expose passwordHash in API responses
- use the existing AppError class
- add tests for invalid login and expired tokens

Show me the implementation plan first.

The second request isn’t better because it contains some secret prompt-engineering formula.

It is better because it contains engineering decisions.

A Workflow I Find Reliable

For anything beyond a trivial change, this is roughly the loop I prefer:

1. Explain the requirement
          |
          v
2. Ask Claude to inspect existing code
          |
          v
3. Review Claude's understanding
          |
          v
4. Ask for an implementation plan
          |
          v
5. Correct the plan if needed
          |
          v
6. Implement a focused change
          |
          v
7. Run tests / lint / typecheck
          |
          v
8. Review git diff
          |
          v
9. Test important behaviour myself
          |
          v
10. Commit

That isn’t as exciting as saying “one prompt built my entire application.”

It is much closer to how I want software development to work.

Claude Code vs an IDE AI Assistant

I don’t think this needs to become a competition where one tool must be declared the winner.

An IDE assistant can be excellent when I am actively writing code and want completion or help with the file directly in front of me.

Claude Code becomes particularly interesting to me when the task crosses several files or involves the development environment itself.

TaskWhat I Prefer
Complete the next few linesIDE completion can be faster
Explain one functionEither approach works
Trace behaviour across a repositoryAgentic codebase workflow is useful
Change several related filesClaude Code can be very useful
Run tests and respond to failuresClaude Code workflow fits well
Small manual editI often just edit it myself

I don’t need every task to involve AI.

Sometimes changing three lines myself is faster than explaining those three lines to an agent.

My Claude Code Checklist

Before letting Claude handle a meaningful change, these are the things I want to be true:

  • The requirement is reasonably clear.
  • Claude has inspected the relevant existing code.
  • Important project rules are documented in CLAUDE.md.
  • The scope of the change is explicit.
  • Security-sensitive commands still require appropriate review.
  • External input is not blindly trusted.
  • Tests are part of the implementation.
  • The relevant verification commands are run.
  • I review the final diff.
  • I understand what I’m about to merge.

Is Claude Code Worth Using?

For the way I work, the useful question isn’t whether Claude Code can write code faster than I can type.

Typing was rarely the slowest part of software development in the first place.

The slower parts are often:

  • understanding an unfamiliar area
  • finding all the places affected by a change
  • investigating why something failed
  • writing repetitive supporting code
  • checking whether an implementation follows existing patterns

Those are the places where I think an agent working with the repository can be genuinely useful.

But I wouldn’t measure success by how autonomous I can make it.

I measure success by whether I can deliver correct software with less unnecessary work while still understanding the result.

Final Thoughts

Claude Code has become a much more capable development tool than the simple terminal assistant I first wrote about.

It can understand repositories, edit files, execute development commands, work with persistent project instructions, connect to external tools through MCP, delegate focused work to subagents and automate deterministic workflows with hooks.

Those capabilities are useful.

They also make developer judgment more important, not less.

The workflow I prefer is straightforward:

Give Claude good context, let it investigate, agree on the plan, keep the change focused, verify the result and review what actually changed.

When I work that way, Claude Code feels less like a tool that is trying to “replace coding” and more like a useful addition to the engineering workflow.

And that is the way I think AI coding tools are most valuable.

Continue Learning

If you’re exploring Claude Code and AI-assisted development, these guides continue from here:

Share this guideLinkedInPost

ARTICLE TOOLKIT

Save or share this guide

Keep the reference nearby or send it to a teammate solving the same problem.

Share this guideLinkedInPost

QUALITY NOTE

Written from practical development experience and reviewed for clarity. Found an outdated step?

Report a correction →

Jaydip Barad

WRITTEN BY

Jaydip Barad

Senior full-stack developer sharing production-tested lessons from 14+ years of building backend systems, WordPress platforms and modern JavaScript applications.

Node.jsTypeScriptWordPressArchitecture
Previous guide
Next guide

THE PRACTICAL DEVELOPER LETTER

Get useful engineering lessons without the noise.

New tutorials, architecture notes and tools worth knowing—delivered occasionally.




    Occasional practical tutorials. Unsubscribe any time.