In this article

🧭 What Claude Code is, and why it lives in the terminal

Claude Code is Anthropic's CLI: an agent you open inside your project folder and talk to in plain language. What sets it apart from IDE autocomplete isn't the quality of the generated code — it's that the agent acts. It reads the files it needs, edits several in one go, runs the tests, reads the error and tries again.

The terminal isn't an aesthetic choice. A useful agent has to do the same things you do while developing: git, the build, the tests, the repo's own scripts. Living where those commands live removes a translation layer — and it's also why it behaves the same locally, inside a container, or in CI.

The practical consequence is that the work shifts: you write less code by hand and spend more time describing the goal and verifying the result. That's only a good trade if verification is fast and reliable, which is why half this guide is about guardrails rather than prompting.

  • Works in the project folder, with your own tools and scripts.
  • Edits several files at once and verifies itself by running commands.
  • Same experience locally, in containers and in CI.

⚡ Install and first run

You need Node.js 18 or newer. Installation is a global package, and the first claude you launch inside a folder opens the interactive session and asks you to authenticate (Claude subscription or API key).

The advice I always give: make your very first session a repo you wouldn't mind losing, and ask for something harmless — "explain how this project is organised". The point is to watch how the agent asks permission before touching anything, which is the thing worth understanding first.

Install and first session · Bash
# 1) Global install (needs Node 18+)
npm install -g @anthropic-ai/claude-code

# 2) Enter the project folder and open a session
cd ~/projects/my-repo
claude

# 3) Useful right away: a single question, no interactive session
claude -p "summarise the structure of this repo"

Official documentation — installation

🧠 The mental model: context, permissions, turn

Three concepts explain almost every behaviour that looks odd at first.

Context is what the agent has in front of it right now: the conversation plus the files it has read. It is not permanent memory — close the session and it's gone. Nearly every "but I already told you" frustration starts here, and it's solved by writing whatever must always hold into a file (next chapter).

Permissions decide what it can do without asking. It's the dial between "it stops me on every line" and "it just did something I didn't want". The turn is the unit of work: you ask, the agent works as long as it needs — possibly many minutes and many commands — then stops. Knowing where a turn ends matters, because that's where automatic checks hook in.

  • Context: volatile, per session. Anything that must always hold goes in a file.
  • Permissions: what the agent does on its own versus what it must ask about.
  • Turn: the unit of work, and the point where you can attach a gate.

📄 CLAUDE.md — the rules the agent always reads

CLAUDE.md is a markdown file at the root of the project that the agent loads in every session. It's where you put what you're tired of repeating: the right package manager, code style, the test commands, the things never to touch.

My first mistake was writing it too long. Every line takes up context in all sessions, including the ones where it's irrelevant. The rules that work are few, specific and checkable: "use yarn, never npm" works; "write clean code" doesn't, because nothing can verify it.

My second mistake was describing the project structure. The agent discovers that by itself, and the moment you rename a folder the file starts lying. Write only what is not derivable from the code: conventions, constraints, decisions already made. I went deeper on this in the tips post about CLAUDE.md.

CLAUDE.md · a minimal example
# Project — rules

## Constraints not derivable from the code
- Package manager: **yarn**, never npm.
- Tests run with `yarn test` (vitest), not jest.
- `src/legacy/` is frozen: don't touch it without asking.

## Style
- TypeScript everywhere, no `any`.
- No braces on single-statement `if`.

Official documentation — memory and CLAUDE.md

⚙️ settings.json and permissions

If CLAUDE.md tells the agent how to work, settings.json tells it what it's allowed to do. It lives in .claude/settings.json (shared with the team, version-controlled) or in ~/.claude/settings.json for your personal preferences.

The part that genuinely changes your day is permissions: an allow list for safe, repetitive commands and a deny list for what it must never touch. Putting harmless reads in allow — git status, ls, the tests — removes most interruptions without giving up control where it matters.

On deny I'm categorical: secrets files go in it. Not because I expect malicious behaviour, but because a .env read by accident lands in the context, and from there potentially into a log or a request. The configuration details are in the settings.json article.

.claude/settings.json · permissions
{
  "permissions": {
    "allow": [
      "Bash(git status)",
      "Bash(git diff:*)",
      "Bash(yarn test)"
    ],
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./**/secrets/**)"
    ]
  }
}

Official documentation — settings

🔌 MCP — giving the agent external tools

The Model Context Protocol is the standard an agent uses to talk to systems that aren't the filesystem: a database, an issue tracker, a browser, your internal APIs. An MCP server exposes tools; Claude Code sees them and uses them when needed.

This is the moment the agent stops being "something that writes code" and becomes "something that can look at the real data". A concrete example from my own work: with the MongoDB MCP server connected, instead of describing a collection's shape in words, the agent queries it.

My advice is to add them one at a time. Every server brings its tool descriptions into context, so wiring up ten "just in case" costs tokens in every session and muddies the agent's choices. I've written both about adding them to Claude Code and Codex and about configuring them in VS Code.

  • One MCP server = a set of external tools exposed to the agent.
  • Typical transports: stdio locally, HTTP for remote servers.
  • Add one at a time: each one costs context in every session.

🪝 Hooks — making deterministic what the model forgets

Hooks are shell commands Claude Code runs at fixed points of the lifecycle: before using a tool, after an edit, when the session is about to close. They aren't prompts: they're code that always runs.

That distinction is why they matter. A rule written in CLAUDE.md is an instruction the model usually follows; a hook is a gate it cannot route around. If the formatter must run after every edit, a PostToolUse guarantees it 100% of the time, whereas "remember to format" has a success rate.

The two I use on every project: a PreToolUse that blocks reads of secrets files — the safety net underneath the permission deny — and a Stop that re-runs the tests when the agent tries to declare itself done. Exiting with code 2 blocks the close, and the error message goes back to the agent as an instruction.

Stop hook · the test suite as a gate
#!/usr/bin/env bash
# .claude/hooks/test-gate.sh — attached to the Stop event.
# Exit 2 = block the turn from closing; stderr goes back to the agent.

if ! yarn test --silent 2>&1; then
  echo "Suite is red: fix the tests before saying you're done." >&2
  exit 2
fi

Official documentation — hooks

🤖 Subagents — delegating without polluting the context

A subagent is a separate agent, with its own context and tools, that the main agent can hand a task to. Only the result comes back: all the intermediate noise — files read, failed attempts — stays in its context instead of yours.

It helps in two cases. Broad searches, where answering one question means reading twenty files: the subagent reads them and reports the conclusion. And independent checks, where a second agent re-reads the first one's work with fresh eyes — a reviewer who isn't attached to the code being judged.

You configure them with the /agents command, which writes one file per agent with its prompt and tools. My advice is to give each one a single, well-defined job: generic subagents tend to return vague summaries.

🧩 Skills and plugins — packaging your own method

A skill is a written procedure the agent loads when needed: your way of doing a code review, the steps of a release, the conventions for a certain kind of file. It lives in a folder with a SKILL.md and a description saying when to use it — and that description is what decides whether it gets invoked at the right moment.

The difference from CLAUDE.md is cost: project rules weigh on every session, a skill only weighs when it's used. That makes it the right home for long procedures needed rarely.

Plugins are the next step: they package skills, hooks, subagents and commands into something installable and shareable through a marketplace — even a plain GitHub repo. It's how a method stops living on your machine and becomes something the team installs.

  • Skill: one procedure, loaded on demand. The description says when to use it.
  • Plugin: skills + hooks + subagents + commands, installed together.
  • Marketplace: even just a GitHub repo with a manifest file.

💸 Context and cost — /compact, --resume and limits

Context is finite, and when it fills up answers get worse before they stop working. /compact summarises the conversation so far and restarts with room to spare: the right moment to use it is when you finish a piece of work, not when the agent starts getting confused.

--resume reopens a previous session with its context. It's the answer to "do I have to explain everything again tomorrow morning?": if the work continues, resume the session instead of starting a new one.

On spend, the rule that saved me the most isn't an option but a habit: short, focused sessions. A long session carries everything it has read into context, and every later turn pays for it again. Three twenty-minute sessions on three separate problems cost less than one hour-long session covering all three.

  • /compact when a task ends, not once quality has already dropped.
  • --resume to continue, instead of rebuilding context from scratch.
  • Short, focused sessions: the single most effective lever on cost.

🧪 The method — TDD and review as guardrails

This is the part that matters more than any configuration. An agent produces plausible code very quickly; the bottleneck becomes verifying it's correct. If verification is slow or sloppy, you hand back all the speed you gained in debugging.

Test-driven development is the best leash I've found: a test written first is an executable specification, and "done" stops being the agent's opinion and becomes a state of the system. Combined with the Stop hook from the hooks chapter, it becomes a criterion that enforces itself.

The second guardrail is review, and it's worth not having it done by the same agent that wrote the code: whoever just produced a solution tends to find it convincing. A second model with clean context, or automated review on the pull request in CI, catches things that slip through.

🆚 Claude Code and the alternatives

It isn't the only agent around, and it isn't always the right choice. GitHub Copilot is still unbeatable at completion inside the editor: if what you want is to write code faster line by line, that's a different job. Cursor brings the agent inside a full IDE, and for people who dislike the terminal that changes everything.

Where Claude Code pulls ahead is long, multi-step work: refactors touching twenty files, migrations, "make this suite pass" — anything requiring read, try, fix and retry without you approving each individual step.

The honest answer is that they don't exclude each other: I use editor completion while typing and switch to the agent when a task has more steps than lines. The detailed comparison with Copilot, Cursor and Gemini is in a separate article.

✅ Checklist — from zero to a setup that holds

Order matters: each step makes the next one useful. Stop after the fourth and you already have 80% of the value, and the first three fit in one evening.

  • 1. Install it, open a session on a harmless repo, ask a read-only question.
  • 2. Write a short CLAUDE.md: package manager, test command, what not to touch.
  • 3. Set permissions: allow for repetitive commands, deny for secrets files.
  • 4. Adopt a checkable definition of "done" — the tests — and accept no other.
  • 5. Add a Stop hook that enforces that definition on its own.
  • 6. Connect your first MCP server. One. The one you actually need.
  • 7. When you notice yourself repeating a procedure, turn it into a skill.
  • 8. When the skill is useful to others too, package it as a plugin.

Frequently asked questions about Claude Code complete guide

Is Claude Code free?

No: it needs a Claude subscription or an API key billed per token. Installing the CLI is free, but using it goes through a paid account. The real cost depends far more on habits than on the plan: short, focused sessions consume much less than one long session dragging along everything it has read so far.

What's the difference between Claude Code and GitHub Copilot?

They're two different jobs. Copilot completes code as you type, inside the editor, line by line. Claude Code is an agent: you describe a goal and it reads files, edits several of them, runs the tests and fixes things itself. Copilot wins on typing speed, Claude Code on long multi-step work like refactors and migrations.

Do I need to know how to code to use Claude Code?

To get anything useful out of it, yes. The agent speeds up people who can already read code and recognise when a solution is wrong; without those skills there's no way to notice that a plausible result isn't a correct one. The skill that matters most isn't writing code, it's verifying it.

How do I stop Claude Code from reading my .env file?

On two levels. First, a deny rule in the settings.json permissions covering the paths of sensitive files. Second, a PreToolUse hook that intercepts the read and write tools and blocks them on forbidden paths, exiting with code 2. The second level matters because it's code that always runs, not an instruction the model might interpret.

What's the difference between CLAUDE.md, a skill and a hook?

They differ in when they act and how binding they are. CLAUDE.md is rules loaded in every session: they always cost context and the model usually follows them. A skill is a procedure loaded only when needed, so it doesn't weigh for nothing. A hook is shell code running at a fixed lifecycle point: not an instruction, but a gate the agent cannot route around.

Can Claude Code work with local models through Ollama?

Not directly, but there are routers that sit in between and route requests to a local model or to the cloud depending on the task. It's a way to keep work on sensitive code in-house and use the large model only where it genuinely helps. I wrote a dedicated tutorial on that setup.

Let's talk

If this topic is relevant to you, write to me: comparing notes on code and AI is always time well spent.

All articles