Founders ProgramFrom idea to company in 30 days. Apply ›
← Blog

Claude Code in Practice: How to Actually Get Good at It

It's not about prompting. It's about building the system around the tool.

March 2026

Most developers use Claude Code like a chatbot with file access. Type a request, get code back, paste it somewhere. That works for small tasks, but it leaves most of the tool's value on the table.

After six months of building products with Claude Code every day, we've found that the gap between an average session and a great one has almost nothing to do with how you write your prompts. It's about the system you build around the tool.

This is what actually matters.

It's a systems problem, not a prompt problem

The instinct is to get better at prompting. Write more detailed instructions. Add examples. Be more specific. That helps incrementally, but it's a local optimum.

Claude Code has six surfaces you can control. Each one changes how the tool behaves. Focusing on just one, usually prompting, while ignoring the others means you're tuning 15% of the system and wondering why the results are inconsistent.

Six layers of control

1
CLAUDE.md / Rules
2
Tools / MCP
3
Skills
4
Hooks
5
Subagents
6
Verification

CLAUDE.md and rules set long-term context: project conventions, safety rails, build commands. Always in context, always shaping behavior.

Tools and MCP define what Claude can do beyond reading and writing files. Connect it to your database, your deployment pipeline, your browser.

Skills are on-demand workflow packages. A deployment checklist. A migration protocol. They load when invoked and stay out of context otherwise.

Hooks are deterministic scripts that fire on specific events. Auto-format after every edit. Block modifications to protected files. They can't be forgotten because they don't depend on Claude “deciding” to follow a rule.

Subagents are independent Claude instances spawned for isolated tasks. They get their own context window, do their work, and return results without polluting your main conversation.

Verification is how Claude checks its own work. Tests, type checks, lint, screenshots. Without this, you're reviewing everything manually. With it, Claude iterates until the code actually works before you ever see it.

Over-investing in one layer while ignoring the others creates a fragile system. A perfect CLAUDE.md won't save you if there's no verification. Great skills are useless if context is overloaded. The goal is balance across all six.

Context is the real constraint

Claude Code has a 200K token context window. That sounds generous until you see where the tokens actually go.

200K context window

Where your tokens actually go before you start working

~25K
~152K
System prompt
MCP tools (×5)
CLAUDE.md + rules
Available for work

The system prompt alone takes around 18K tokens. Each MCP server adds 4,000 to 6,000 tokens for tool definitions. Connect five servers and you've consumed 12 to 15% of your context before writing a single prompt. Add file reads, a few back-and-forth exchanges, and you're at 40% before real work begins.

This matters because performance degrades as context fills. Instructions from the first message get diluted by message thirty. Constraints you set early start getting ignored. Claude's behavior drifts, and you spend more time correcting than creating.

Practical rules for context

Compact at 60%, not at the limit. Manual compaction while there's still headroom produces better summaries than auto-compaction at the wall. Use /compact with a focus instruction: /compact Focus on the API migration decisions.

Clear between tasks. Different task, different context. /clear isn't losing progress. It's preventing cross-contamination. The five minutes you save by staying in the same session cost you twenty when Claude starts confusing the current task with the previous one.

Use subagents for exploration. When you need to search a codebase or investigate an issue, spawn a subagent. It gets its own context. The results come back without flooding your main conversation with thousands of lines of file contents.

Layer your context loading. CLAUDE.md is always loaded. Rules activate based on the directory you're working in. Skills load on demand. This progressive disclosure exists for a reason. Use it instead of cramming everything into CLAUDE.md.

CLAUDE.md is the highest-leverage file in your repo

This one file has more impact on agent productivity than your model choice, your prompt style, or any other configuration. It's the only file automatically included in every conversation.

The mistake most teams make is treating it like documentation. CLAUDE.md isn't a wiki. It's a contract. Every line should exist because Claude would do the wrong thing without it.

What belongs

  • Build, test, lint, and type-check commands that Claude can't guess from package.json
  • Architecture boundaries: what lives where, what never goes where
  • Coding conventions that differ from language defaults
  • Safety rails: NEVER and ALWAYS rules for things that matter
  • Compact instructions: what to preserve during context compression

What doesn't belong

  • Anything Claude can figure out from the code itself
  • Standard language conventions (Claude already knows them)
  • Long explanations, tutorials, or file-by-file descriptions
  • Linting rules (use hooks for deterministic enforcement)

Keep it under 200 lines. Claude Code's system prompt already uses roughly 50 of the ~200 instructions frontier models follow consistently. Every unnecessary line in CLAUDE.md competes with the ones that actually matter.

The maintenance pattern: every time you correct Claude on the same thing twice, add it to CLAUDE.md. Review monthly and remove rules that are stale. Boris Cherny, who built Claude Code, says his team updates theirs multiple times a week. The whole team contributes. It's a living document that encodes how the agent should behave in their specific codebase.

Plan first, then let it run

The most effective workflow pattern: start every non-trivial task in plan mode.

Press Shift+Tab twice. Claude switches to plan mode. It reads files, analyzes the codebase, and proposes an approach without writing any code. You go back and forth until the plan is right. Then switch to normal mode and let it execute.

~/project

This seems like it adds a step. It actually saves time. A bad plan caught in 30 seconds prevents the 20-minute debugging session after the agent builds the wrong thing. The plan is cheap. The wrong implementation is expensive.

For complex work, open the plan in your external editor with Ctrl+G. Edit it directly. Add constraints. Remove unnecessary steps. Then let Claude execute against your edited plan.

After the plan is approved, switch to auto-accept mode for edits. Claude can usually one-shot a well-planned implementation without needing intervention on every file change.

Verification is what separates good from great

The single highest-leverage action you can take: give Claude a way to check its own work.

Without verification, Claude writes code that looks correct. With verification, Claude writes code that is correct, because it runs the tests, sees the failures, and fixes them before you ever look at the output.

The loop: write code, run tests, fix failures, repeat until green. This works because tests are a deterministic signal. Claude doesn't need to “understand” whether the code is right. It just needs the tests to pass.

What counts as verification:

  • Running the test suite after every change
  • Type checking ( tsc, mypy) catches what tests miss
  • Building the project to verify nothing breaks at compile time
  • The Chrome extension, which lets Claude navigate your actual UI, click buttons, fill forms, and screenshot the result

The Chrome extension deserves special mention. For UI work, it turns Claude from “write code and hope it looks right” into “write code, check the result, iterate until it matches.” A team without verification reviews every change manually. A team with verification reviews changes that already work.

Parallel sessions for parallel work

One Claude Code instance is productive. Five running simultaneously is a different category.

The pattern: identify independent tasks that don't touch the same files. Give each its own terminal, its own branch, its own context. Let them all run. Review the diffs as they come in.

A typical day:

  • Terminal 1: Building a new API endpoint
  • Terminal 2: Writing tests for an existing feature
  • Terminal 3: Refactoring a component
  • Terminal 4: Fixing a bug in a different service
  • Terminal 5: Updating documentation

Each instance works at full speed with fresh context. No cross-contamination. You review five diffs and merge five branches in the time it used to take to ship one feature.

Git worktrees make this clean. Each instance gets its own working directory, its own branch. No conflicts during development. Conflicts only happen at merge time. Claude Code supports this natively: claude --worktree feature-auth spins up an isolated copy of your repo on a new branch.

The constraint is real: tasks must be genuinely independent. Two agents editing the same file produce conflicts. Two agents working on features that interact make assumptions about each other's output. Independence is the prerequisite for parallelism.

Hooks, skills, and subagents

These three layers handle what CLAUDE.md can't.

Hooks: deterministic enforcement

Anything that must always happen should be a hook, not a CLAUDE.md instruction. Instructions can be forgotten as context fills. Hooks can't.

  • PostToolUse auto-formats code after every edit. Prevents CI failures from formatting inconsistencies.
  • PreToolUse blocks modifications to protected files. A hard gate, not a suggestion.
  • Notification alerts you when Claude needs input. So you can step away while it works.

Skills: on-demand knowledge

Unlike CLAUDE.md (always loaded) or rules (path-dependent), skills load only when invoked. This keeps context lean while giving Claude access to complex workflows when needed.

Good skills are specific: a deployment checklist, a migration protocol, a code review workflow. Bad skills are grab-bags of loosely related information. Keep each under 500 lines with concrete examples.

Subagents: context isolation

The primary value of subagents is isolation, not parallelism. A subagent exploring your codebase to answer a question consumes thousands of tokens reading files. If that happens in your main context, you lose working space. If it happens in a subagent, only the answer enters your conversation.

Use subagents for: codebase exploration, research tasks, repetitive operations across many files, anything that would consume context you'd rather keep clean.

The three-layer pattern

For reliable enforcement, use all three together:

  • CLAUDE.md declares the requirement (“all changes must pass type checking”)
  • A skill teaches the execution order and how to interpret failures
  • A hook runs the check automatically on every edit

Any single layer has gaps. All three together is robust.

Commands worth memorizing

Most developers use five commands. There are about twenty that matter. Here are the ones we reach for daily.

Context management

  • /clear resets context completely. Use between tasks.
  • /compact <focus> compresses context with a custom focus instruction.
  • /context shows where your tokens are going. Run this when things feel slow.
  • /rewind or Esc+Esc undo back to a previous checkpoint.

Session control

  • Shift+Tab cycles between Normal, Auto-accept, and Plan mode.
  • Esc stops the current operation. Cheap safety net.
  • Ctrl+G opens the current prompt or plan in your external editor.
  • Ctrl+O toggles verbose mode to see Claude's thinking.

Workflow shortcuts

  • /effort adjusts thinking depth. Use auto for most work, max for hard problems.
  • /btw for side questions that don't enter context. Underappreciated.
  • /permissions allowlists safe commands so Claude doesn't ask for permission every time it runs npm test.
  • # prefix saves something to permanent memory across sessions.

Anti-patterns that waste hours

Kitchen-sink sessions
CLAUDE.md as a wiki
Correcting the same mistake 3x
Trusting without verifying
Sessions that run for hours
Max effort for everything

The kitchen-sink session. Mixing unrelated tasks in one conversation. Claude loses track of which constraints apply to which task. You end up correcting mistakes that wouldn't exist in a fresh context.

Over-engineering CLAUDE.md. Pages of detailed instructions that Claude can't follow because there are too many competing priorities. The fix: keep it under 200 lines, convert enforcement rules to hooks, move detailed workflows to skills.

Correcting the same mistake three times. If Claude keeps getting something wrong after two corrections, the original prompt wasn't clear enough. Run /clear and write a better prompt from scratch. Then add the correction to CLAUDE.md so it never happens again.

Trusting the first result. Claude's output looks polished and confident even when it's wrong. The surface quality masks deeper issues. Always verify. Run tests. Read the diff line by line.

Sessions that run for hours. Context degrades. Performance drops. Claude starts referencing its own earlier statements instead of the actual codebase. A fresh start costs seconds. A degraded session costs minutes of confused output you'll have to undo.

Using max effort for everything. Higher thinking effort isn't always better. Simple tasks get slower without getting more accurate. Use /effort auto for most work, and save max for complex refactors and hard bugs.

Session handoffs: the HANDOFF.md pattern

Context compression is lossy. When Claude auto-compacts a long conversation, it optimizes for readability, not for preserving the architectural decisions you made in message five. Those decisions, the ones that shaped every subsequent choice, often get summarized away.

The fix: before ending a session that another session will continue, write a HANDOFF.md file. Document what was tried, what worked, what failed, and what comes next. The next Claude instance picks up from this file instead of depending on compression quality.

This matters most for multi-session features. A feature that takes three sessions without handoff notes will have the third session reinventing decisions the first session already made. With handoff notes, session three starts with full context in a few hundred tokens instead of hoping the compression preserved what matters.

Prompt caching shapes architecture

This is a technical detail that most developers ignore but that affects every session. Claude Code uses prompt caching to avoid reprocessing the same content on every turn. The cache structure looks like this:

  • System prompt: static, locked in cache
  • Tool definitions: static, locked in cache
  • Chat history: grows dynamically after the cache breakpoint
  • Current user input: always last, never cached

The practical implications:

Don't switch models mid-session. It rebuilds the entire cache. If you need a different model, start a new session.

Don't add or remove MCP servers mid-session. Tool definitions are part of the cached prefix. Changing them invalidates the cache and costs you a full reprocessing pass.

Don't put timestamps or dynamic content in CLAUDE.md. If your CLAUDE.md changes between turns, the cache breaks. Keep it stable.

The three stages of getting good

Getting good at Claude Code follows a predictable progression. Most developers stay at stage one. The multiplier difference between stages is significant.

The gap between stage 1 and stage 3 isn't about knowing more commands. It's about shifting from “how do I make Claude do this” to “how do I build a system where Claude can operate independently.”

At stage 1, you're translating your intent into prompts one task at a time. At stage 3, you've encoded your intent into CLAUDE.md, skills, hooks, and verification loops, and Claude operates within those constraints without needing you to repeat yourself.

The meta-lesson

After six months of daily use, the single most important insight is this:

Without clear acceptance criteria defining “done,” the task isn't ready for autonomous execution, regardless of model capability.

This applies to every layer. CLAUDE.md needs clear rules, not vague guidelines. Tasks need specific outcomes, not open-ended directions. Verification needs deterministic checks, not “does it look right?”

The model will keep getting better. Context windows will grow. Reasoning will improve. But the fundamental pattern won't change: clear intent, bounded scope, mechanical verification.

The teams that build these systems now compound the advantage with every model improvement. The ones still typing prompts into a chat window will keep wondering why the tool doesn't work as well for them.

Start with CLAUDE.md. Add verification. Then build from there.

Buildway partners with founders to build what's next. We bring engineering, agents, and operations so you can focus on product and customers.

Get in touch