Most people who try Claude Code bounce off it. They install it, ask it to fix a bug, watch it edit six files they didn’t expect, get spooked, and close the terminal. Six months later they quietly come back because everyone they respect won’t shut up about it, and the second try sticks.
This primer is the second try, pre-loaded. It’s the thing I wish someone had handed me on day one: what Claude Code actually is, how to set it up so it doesn’t scare you, the handful of features that separate a tourist from a daily driver, and the habits that keep you shipping instead of cleaning up.
This is the anchor primer for the Coding Agents track. If you read one thing in this section first, read this one.
What Claude Code actually is
Claude Code is a terminal-native coding agent. You run claude inside a repo, and you get a chat interface where the model has a real set of tools: it can read files, edit files, run shell commands, spin up subagents, and call into MCP servers you’ve configured. It’s not a chatbot that suggests code you paste in. It’s not fancy autocomplete. It’s an agent that executes.
Three things follow from that framing and matter more than any individual feature:
- It has side effects by default. When you ask Claude Code to “fix the failing test,” it will actually edit files on disk and run your test runner. If you’re used to ChatGPT giving you a snippet to copy, this is a different posture.
- It lives in your repo. It reads your code, your
CLAUDE.md, your config. Context isn’t a text box; it’s the filesystem. - It’s composable. Hooks, skills, subagents, MCP servers, and the settings hierarchy are all orthogonal primitives. Most of your growth as a power user is learning which primitive to reach for, not learning more prompts.
The rest of this primer is a guided tour of those primitives, plus the habits that glue them together.
Install and first login
npm install -g @anthropic-ai/claude-code
claude --version
That gives you a claude binary on your path. First time you run it, you’ll be prompted to authenticate:
claude /login
Log in with your Anthropic account. Claude Code can use either your Claude.ai subscription or a pay-as-you-go API key; the login flow handles both. If you’re on a team plan or have an organization account, pick the right workspace when prompted — it determines which models you have access to and where usage gets billed.
If you don’t have Node, install it first. The binary has no other runtime dependencies beyond what your shell already has.
Your first session
Change into a repo you care about and type claude. Three things happen that are worth understanding up front:
- It looks for a
CLAUDE.mdat the repo root. If it finds one, it loads it into the system prompt as project-wide instructions. This is how you teach Claude Code about your codebase without retyping the same hints every session. - It loads your auto-memory. Claude Code keeps a long-running memory file per project (under
~/.claude/projects/<encoded-path>/memory/MEMORY.md). Facts you’ve asked it to remember — the port your dev server runs on, the name of your deploy script, which test runner you use — persist across sessions. - It shows a prompt, and waits. Type anything. A question, a task, “what does this repo do.” You’re in.
The first task I give any new project is boring on purpose: “Read through the repo and summarize the architecture.” It’s a read-only task, it forces the model to orient itself, and it surfaces any CLAUDE.md gaps before I start giving it real work.
Don’t start with “refactor the auth layer.” Start with “tell me what’s here.”
Plan mode: when to use it
Plan mode is the first feature that separates casual users from people who don’t break things.
By default, Claude Code can edit files and run commands as soon as you ask for them. For small tasks this is exactly what you want. For larger tasks — anything spanning multiple files, anything touching config, anything you’re not 100% sure the model has understood — you want it to plan first, then execute.
Enter plan mode with Shift+Tab (or start a message with “plan:”). In plan mode, Claude Code is in a read-only posture: it can read files and run read-only commands, but it cannot edit or write. It will produce a structured plan — a list of files it intends to change and what changes it intends to make — and then call the ExitPlanMode tool to hand the plan back to you for approval.
You get three choices at that point:
- Approve and execute. The plan becomes the work. Claude Code exits plan mode and starts editing.
- Edit the plan. Respond with corrections or additions. The model revises the plan. Loop until you’re happy.
- Reject. Stay in plan mode. Ask new questions. Bail out entirely.
The habit that makes plan mode useful: treat the approval step as a real review. Read the plan. Check it matches your mental model. If the model proposes editing a file you didn’t expect, that’s a signal — either the task is bigger than you thought, or the model is off-track. Either way, you want to know before it writes code, not after.
My rule of thumb: if the task is “smaller than a commit,” execute directly. If the task is “bigger than a commit,” plan first.
The settings hierarchy
Claude Code has four places it reads settings from, with a clear precedence order. Knowing which file to edit for which setting is one of the highest-leverage pieces of knowledge in the whole system.
| File | Scope | Committed? | What goes here |
|---|---|---|---|
~/.claude/settings.json | User-global | No (it’s in your home dir) | Personal preferences, your API key, personal MCP servers, global hooks |
.claude/settings.json | Project | Yes | Project-level MCP servers, team hooks, permissions everyone should share |
.claude/settings.local.json | Project, per-user | No — gitignore it | Personal overrides for this project: auto-accept permissions, local-only MCP, machine-specific paths |
| CLI flags | Single invocation | N/A | One-off overrides |
Claude Code merges these in order — project settings layer on top of user settings, and .local.json layers on top of both. More specific wins.
A minimal .claude/settings.json for a project might look like:
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_TOKEN": "${env:GITHUB_TOKEN}" }
}
},
"permissions": {
"allow": [
"Bash(npm run test:*)",
"Bash(npm run build)",
"Read",
"Edit"
]
}
}
The matching .claude/settings.local.json (gitignored) might look like:
{
"permissions": {
"allow": [
"Bash(./deploy.sh --dry-run)"
]
}
}
That keeps the team-shared rules in the committed file and your personal “yes, I’m fine with this running the dry-run deploy” preference local to your machine.
For the full tour — including the whole permissions DSL, nested projects, and the quirks that bite you — see the deep dive at /guides/vscode-settings-local-json. The short version: put project-wide rules in .claude/settings.json, put personal overrides in .claude/settings.local.json, and never commit the .local.json.
CLAUDE.md as the project brain
CLAUDE.md is a plain Markdown file at your repo root. Claude Code loads it into the system prompt at the start of every session. It’s the single highest-leverage file in the entire setup.
What belongs in it:
- What the project is. One paragraph. “This is the Astro site for herdingbots.ai. It’s a portfolio + content hub.” Orient the model.
- Tech stack. Languages, frameworks, major libraries. A table works well.
- Directory structure. A tree with a one-line explanation per directory. This is usually the single biggest win — it stops the model from guessing where things live.
- Conventions that aren’t obvious from the code. “We use Tailwind v4 with CSS-first config. Never create
tailwind.config.js.” “All deploys are static — no Node runtime in production.” “Content goes insrc/content/, notsrc/pages/.” - Common commands.
npm run devruns on port 7000 in this repo because of a conflict../deploy.sh --dry-runpreviews without pushing. Things the model would otherwise get wrong. - Anti-patterns specific to this codebase. “Don’t use
letfor module-level state — we’ve been burned by it.” Save yourself from re-teaching the same lesson.
What does NOT belong in it:
- General coding advice. “Write clean code” is noise. The model already knows.
- Long prose essays. Every token in
CLAUDE.mdis loaded into every session’s context. Keep it tight. - Secrets. Obvious but worth saying.
CLAUDE.mdis committed; don’t put credentials there. - Things that change often. If you find yourself editing
CLAUDE.mdtwice a day to keep it in sync with some moving target, you’ve got the wrong tool. Move that into a doc the model can read on demand.
A realistic skeleton:
# MyProject
Short description of what this is and who it's for.
## Stack
| Layer | Choice |
|---|---|
| Runtime | Node 20 |
| Framework | Next.js 14 (App Router) |
| DB | Postgres via Prisma |
| Styling | Tailwind v4 |
## Directory structure
\`\`\`
src/
app/ # Next.js App Router pages and layouts
components/ # Shared React components
lib/ # Business logic, DB access
styles/ # Global CSS
tests/ # Vitest integration tests
\`\`\`
## Conventions
- Pages in `src/app/` only call helpers from `src/lib/`. No direct DB access in components.
- All DB access goes through Prisma. No raw SQL outside `lib/db/queries/`.
- Tailwind v4 CSS-first. Never create `tailwind.config.js`.
## Common commands
\`\`\`bash
npm run dev # dev server at localhost:3000
npm run test # vitest
npm run migrate # prisma migrate dev
\`\`\`
For monorepos and other layouts where one CLAUDE.md isn’t enough — nested CLAUDE.md files per package, workspace-specific conventions, the patterns for keeping them in sync — see /guides/claude-md-monorepo-structure.
The feedback loop on CLAUDE.md is simple: every time Claude Code gets something wrong in a way that a one-liner would have prevented, add that one-liner to CLAUDE.md. Do that for two weeks and the quality of your sessions roughly doubles.
Hooks: the harness reacting to events
Hooks are shell commands that Claude Code runs at specific points in its lifecycle. They’re the single most underused power-user feature.
The lifecycle events hooks can listen to:
| Hook | Fires when | Typical use |
|---|---|---|
SessionStart | A new session begins | Set env vars, print a project banner, check git status |
UserPromptSubmit | You submit a prompt | Log prompts, inject context, gate certain asks |
PreToolUse | Claude is about to call a tool | Block dangerous actions, log intent, redact secrets |
PostToolUse | A tool call just finished | Run formatters, update a changelog, notify external systems |
Stop | Claude finishes responding | Play a sound, send a desktop notification, commit a checkpoint |
Hooks are configured in settings.json under "hooks". Minimal example — play a sound when Claude finishes a response:
{
"hooks": {
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "afplay /System/Library/Sounds/Glass.aiff"
}
]
}
]
}
}
That’s ten lines of JSON and a sound effect. It changes your whole workflow because you stop sitting there watching the terminal; you alt-tab to email, and the chime tells you when to come back.
There’s a full walkthrough of the audio-alert pattern, including per-session volume control and how to debounce it so back-to-back completions don’t spam you, at /guides/claude-code-audio-alert-stop-hook.
Other hooks I reach for regularly:
PreToolUseonBashto block anything touching production. A tiny script that greps the command forprod,--force, or production hostnames and blocks the call.PostToolUseonEditto run Prettier. Keeps formatting consistent without asking the model to remember.SessionStartto print the current git branch and any uncommitted changes. Five lines of output that remind you what state the repo’s in before you start.
The mental shift hooks require: the harness executes them, not Claude. If you want automatic behavior — “every time a file gets edited, run the linter” — that’s a hook, not a CLAUDE.md instruction. Telling the model in CLAUDE.md to “always run the linter after editing” works about 70% of the time. A hook works 100% of the time.
Skills: scoped capability packs
A skill is a bundle that extends Claude Code’s capabilities in a named, scoped way. At minimum a skill is a prompt; it can also include hooks and scripts that the skill activates when invoked.
Skills install into ~/.claude/skills/<name>/ and typically contain:
- A
SKILL.mddescribing what the skill does and when to invoke it - Optionally, a hook config that activates only when the skill is in use
- Optionally, a script or set of scripts the skill calls out to
You invoke a skill with /skill-name in the prompt, or Claude Code can invoke them autonomously when their description matches what you’re asking for.
In practice, skills are best for opinionated workflows you want to codify. Things like “run my project’s full release checklist,” “do a security review of the pending diff,” “set up a new feature branch with my standard scaffolding.” Each of these is a sequence of steps that’s stable enough to name and reuse, but too specific to bake into a general model prompt.
The skill ecosystem is evolving fast. There’s a marketplace of community skills, plus a growing set of official ones shipped by Anthropic. Treat skills as a layer you add gradually, not something to front-load. The right pattern:
- Use Claude Code without any skills for a few weeks.
- Notice a workflow you keep repeating.
- Turn it into a skill.
- Keep going.
Front-loading skills before you have workflows that justify them produces drift — you forget what your own skills do and they quietly stop matching reality.
MCP: tool-layer plumbing
MCP (Model Context Protocol) is how Claude Code connects to external tools — GitHub, Postgres, your own internal APIs, anything you can wrap behind an MCP server. In Claude Code, MCP servers are configured under "mcpServers" in your settings.json.
I’m not going to re-explain MCP here; there’s a dedicated primer for that. Read /primers/mcp-in-20-minutes for the mental model, the protocol basics, and a full install walkthrough.
What’s specific to Claude Code:
- Settings hierarchy applies. User-global MCP servers in
~/.claude/settings.json, project-level ones in.claude/settings.json, personal overrides in.claude/settings.local.json. The rules match what you’d expect. - Tool budget is real. Every connected MCP server contributes tool schemas to the context window. Ten servers with ten tools each is 100 tools in the system prompt, and model performance drops when there are too many tools to choose from. Keep it tight; disconnect what you’re not using.
- Restart on config changes. Claude Code reads MCP config at session start. Edit settings.json, restart
claude, and the new servers show up. There’s no hot-reload.
The combo of MCP + Claude Code is where the agent framing really lands. Once your model can read your GitHub, query your Postgres, and poke at your staging API, it stops being a coding assistant and starts being an engineer who knows your system.
Subagents: isolating long work
A subagent is a separate Claude instance that your main session spawns to handle a specific task. The main session gives the subagent a prompt and a narrower toolset; the subagent works on its task in isolation, reports back with a summary, and its detailed transcript is discarded.
You use subagents for two reasons:
- Context isolation. Long-running work — a big code search, a multi-step investigation, a lengthy refactor — generates a lot of intermediate tokens. If all of that lives in your main session’s context, you run out of room. A subagent does the work in its own context and returns only the summary.
- Parallelism. You can kick off multiple subagents at once. “Have three subagents each investigate one suspect module, then compare notes” is a real pattern.
You don’t usually invoke subagents by hand — you ask Claude Code to use one. “Spawn a subagent to find every usage of the old API across the monorepo and summarize where the migrations are needed” is a natural phrasing.
Heuristic for when to reach for a subagent:
- Will the work generate more than, say, 30k tokens of intermediate output? Subagent.
- Is the work independent of whatever else is happening in the main session? Subagent.
- Is it small, exploratory, or tightly coupled to what we were just talking about? Inline.
The skill is resisting the urge to always use subagents “to save context.” Subagents have setup cost — spawning, seeding with context, summarizing back — and for small tasks that cost dominates. Use them where they pay off.
Token budget hygiene
This is the single biggest skill that separates a power user from a tourist, and it has nothing to do with any specific feature. It’s just: respect the context window.
The symptoms of bad budget hygiene: sessions that start fast and get slower. Quality that degrades over the course of a long session. Claude forgetting things you told it an hour ago. Responses that start to drift off-topic.
All of those come from the same cause: too much stuff in context.
The habits that fix it:
- Start fresh sessions for fresh tasks. Don’t treat one
claudeinvocation as your whole workday. When you finish a task, if the next task is unrelated,/clearand start over. Your future self will thank you. - Use
/clearaggressively. It wipes conversation history while keeping your CLAUDE.md and settings. Use it any time you’ve finished a thread and are starting a new one. - Don’t paste the whole file. If you want Claude to look at a file, ask it to read the file. Pasting the contents into your prompt puts it in your context twice — once when you paste it, and again when the model reads it.
- Kill the “summarize everything” habit. Asking Claude to summarize the session periodically feels productive; it’s often a context sink. If you want persistence, write it to a file and ask Claude to re-read that file when it matters.
- Use subagents for big side quests. Already covered above, but worth repeating under this lens.
- Watch the context indicator. Claude Code shows you how much of the context window is in use. When it starts creeping past 50%, be intentional about what you add next.
This is a skill, not a trick. Nobody is naturally good at it. You get better by noticing the moments where your session is degrading and asking “is it my context?”
There’s a dedicated primer on how prompt caching changes the cost calculus of all this — once caching is on, you can afford larger stable prefixes — at /primers/prompt-caching-workspace-isolation. The context-window math is separate from the billing math, though; caching makes context cheaper but not bigger.
The habits that actually stick
Everything above is mechanics. The mechanics don’t matter if your workflow doesn’t hold up under pressure. Here’s what survives after a few months of heavy use:
Checkpoint before anything scary. Before any task that’s going to touch more than a couple of files, commit whatever you had. It takes five seconds and gives you a “reset button” if the agent veers off. You can always squash commits later. You cannot always recover lost work.
Always read the diff. When Claude Code says it’s finished, don’t just check that the tests pass. Read the actual diff. Every time. The model is excellent, it is not infallible, and the kinds of bugs that slip past tests are exactly the kinds of bugs you catch by reading the code. This is non-negotiable.
Don’t trust one-shot completions on anything you didn’t plan. If Claude Code makes a change you didn’t explicitly anticipate — “while I was in there, I also cleaned up the error handling in this adjacent function” — treat that as a yellow flag. Read it carefully. Sometimes it’s a win. Sometimes it’s scope creep that introduces a subtle bug.
Give it tasks, not instructions. “Refactor the auth middleware to use JWT” is a task. “Open src/middleware/auth.ts, find the session lookup, replace it with a call to jwtVerify…” is instructions. The model is better at tasks than you’d guess and worse at being micromanaged than you’d guess. State the intent, let it plan, approve the plan.
Talk to it like a colleague, not a terminal. “Can you take a look at why the tests are flaky?” works better than “Debug flaky tests.” The former invites investigation; the latter implies you already know what the problem is. You usually don’t.
Close the loop on CLAUDE.md. Every time Claude Code does something wrong that a CLAUDE.md update could have prevented, update CLAUDE.md immediately. Not “later.” Now. The compound effect over a few weeks is enormous.
Pitfalls
Auto-accepting everything. Claude Code has a mode where it stops asking for permission and just does things. It’s tempting. It’s also how people accidentally rm -rf the wrong directory or commit and push before they’ve read the code. Use it only in disposable environments — a scratch repo, a branch you’re explicitly exploring — and never on main. Scope your permission allowlist narrowly instead.
Running in an untrusted directory. Claude Code is an agent. It executes code. If you open claude inside a repo you just cloned from someone you don’t trust, and ask it to “figure out what this does,” you’re handing that code execution authority. Either vet the repo first or run Claude Code inside a sandbox.
Skill drift. You install a skill because it solved a problem in March. In June, the tool the skill wraps has changed, the skill hasn’t, and Claude is confidently calling an API that no longer exists. Audit your skills every couple of months. Delete the ones you don’t use.
CLAUDE.md bloat. The first version of CLAUDE.md you write will be great. The tenth version, accreted over six months of “just adding a quick note,” will be 800 lines of prose that contradicts itself in three places. Re-read and prune quarterly. Every session loads the whole file, so its quality directly impacts your session quality.
Believing the first tool output. When Claude Code runs a command and gets output, it will interpret that output and move on. Sometimes the output was an error that the model misread as success. Sometimes the test runner printed “passed” while skipping half the suite. The model is not immune to being confidently misled by garbage output. Read the actual output when it matters.
Treating it as a replacement for thinking. The temptation with a very capable agent is to stop planning your own work and let the agent plan it for you. This is fine for small tasks. It is a trap for anything architecturally important. You still have to hold the shape of the system in your head. The agent is better at implementation than you are; it is not better at deciding what to build.
Getting started — the 10-minute path
If you want a concrete on-ramp, here it is:
- Install.
npm install -g @anthropic-ai/claude-code && claude /login. One minute. - Open a repo you know well. Run
claudein it. Don’t pick something pristine; pick something messy and familiar. You want to be able to evaluate the model’s output. - Ask for a project summary. “Read the repo and summarize the architecture in five bullets.” No edits, just reading. This is your first calibration pass — does the summary match your mental model? If yes, the repo is legible. If no, you’ve just discovered what’s missing.
- Try plan mode. Think of a small task — fixing a typo in copy, updating a dependency, renaming a function. Enter plan mode with
Shift+Tab. Watch it produce a plan. Approve or reject. Feel the difference from executing directly. - Write or paste a
CLAUDE.md. Even a minimal one. Stack, directory tree, three conventions. Save. Start a fresh session. Notice the model is more coherent. - Add one hook. Pick a
Stophook that plays a sound. Confirm it fires. You’ve just configured the harness. Everything else is more of the same shape. - Pick one MCP server. Something that connects to a tool you use daily — GitHub is a good default. Install it. Restart. Ask a question that requires using it.
After those seven steps, note which of them you’ve kept using three days later. That subset is your actual daily driver. Most people keep plan mode, CLAUDE.md, and the Stop hook permanently; hooks and MCP servers they collect gradually as real needs arise.
Where to go next
- /guides/vscode-settings-local-json — the full settings-hierarchy deep dive, including the permissions DSL and the gotchas that waste an afternoon.
- /guides/claude-code-audio-alert-stop-hook — the canonical hook example, end to end.
- /guides/claude-md-monorepo-structure — patterns for CLAUDE.md across multi-package repos.
- /primers/mcp-in-20-minutes — the dedicated primer on MCP, which is where most of the interesting tool-layer growth happens.
- /primers/prompt-caching-workspace-isolation — once you’re comfortable with Claude Code, turn caching on and cut your API bill by an order of magnitude.
The progression is predictable: install and first sessions, then CLAUDE.md, then plan mode, then hooks, then MCP, then skills and subagents. Most people land on a stable daily-driver setup within three or four weeks of real use. After that you stop thinking about the tool and start thinking about the work again, which is the whole point.