The Claude Code Subagent Setup I Use to Ship Production TypeScript
See the exact Claude Code subagent setup I use to ship production TypeScript: agent configs, per-task model pinning, when to delegate, and the cost traps.
The Claude Code Subagent Setup I Use to Ship Production TypeScript
What a Claude Code Subagent Actually Is
A Claude Code subagent is a separate Claude instance with its own context window, system prompt, model, and tool set. The main session hands it a scoped task and gets back a result — not the raw work. That separation is the whole point: a subagent reads twenty files, runs a broad search, or chews through a long log, and only its conclusion crosses back into your main thread. The bulky output never touches the context you pay to reprocess on every turn.
This is not a feature tour. It is the exact setup I run day to day to ship React and TypeScript: which agents I keep, which model each one is pinned to, when I delegate, and the cost traps I have learned to avoid. None of it is exotic. The whole point of a good Claude Code subagent setup is that it is boring, predictable, and cheap to run — and that it keeps your main session sharp instead of drowning it in context it will never use again.
Why a Single Main Thread Gets Expensive
Here is the thing most people miss about working in one long Claude Code thread: every turn re-sends the entire conversation to the model. The whole transcript — every file you read, every command you ran, every wall of tool output — is reprocessed on each new message. So the cost and the latency of a turn are not a function of what you just typed. They are a function of everything that came before it.
That changes how you should think about context. Reading twenty files into the main thread to answer one question feels free in the moment. It is not. Those twenty files now ride along in every subsequent turn, billed again and again until you clear or compact the session. A long, file-heavy thread is the single most expensive shape of work in Claude Code, and it gets slower as it goes.
A subagent breaks that compounding. It reads the twenty files in its own context window, distills them into a summary, and returns just that summary. Its bloated context dies the moment it finishes. Your main thread receives a few hundred tokens of conclusion instead of carrying tens of thousands of tokens of raw file content forever. Multiply that across a working day and the difference is not subtle.
The trade-off is real and worth stating plainly: delegation protects the main window, but each subagent call is a separate model request with its own fixed overhead. Spawning five Opus subagents is roughly five full-price requests. So the skill is not "delegate everything." It is knowing when the context you save is worth more than the overhead you spend.
My .claude/agents Setup
A subagent in Claude Code is just a markdown file. The frontmatter carries name, description, an optional tools allow-list, and a model; everything below the frontmatter is the system prompt the agent runs with. Project agents live in .claude/agents/; the ones I want everywhere live in ~/.claude/agents/ and follow me across repositories. My two workhorses are both global.
The field people underrate is description. Claude Code reads it to decide when to hand work to the agent automatically, so it is a trigger, not a label. "Explores the codebase" is a weak description. "Fast codebase exploration for 'where is X defined' and 'what matches pattern Y' lookups; returns a summary, not file dumps" tells the main session exactly when to reach for it. Write the description for the dispatcher, not for a human skimming a list.
The two I keep:
quick-exploreis pinned to Sonnet and handles "where is X defined" or "what matches pattern Y" lookups. It searches, reads what it needs, and returns a concise prose summary instead of dumping raw files into my main transcript. This is the agent that keeps exploration from quietly bloating a session.summarizeris pinned to Haiku and exists to collapse long things — logs, diffs, docs — into something I can actually act on. Haiku is more than enough to turn a thousand-line log into five lines that matter.
I also restrict each agent's tools deliberately. A summarizer does not need Edit, Write, or Bash; giving it read access only means it cannot wander off and start changing files when all I wanted was a digest. A tight tool allow-list is the cheapest guardrail in the whole setup, and it costs one line of frontmatter.
Model Pinning: Match the Model to the Task
The habit that saves the most money is matching the model to the task instead of running everything on the most capable one. Claude Code lets you pin a model per agent, and the three tiers map cleanly onto three kinds of work.
Opus is for the work that actually needs reasoning: architecture, hard debugging, adversarial review, and any code the main thread is going to act on directly. Sonnet is the right default for read-heavy and search-heavy work where you need good comprehension but not deep reasoning — that is why quick-explore runs on it. Haiku is for the high-volume, low-judgment work: summarizing, distilling, reformatting. Paying Opus rates to summarize a log is like taking a taxi to walk the dog.
You pin the model right in the frontmatter, so a cheap task can never silently run on an expensive model:
---
name: quick-explore
description: Fast codebase exploration that returns a summary, not file dumps
model: sonnet
tools: Glob, Grep, Read
---Everything below that frontmatter is the system prompt the subagent runs with. The trap to avoid is leaving every agent on the default Opus "to be safe." A search-heavy workflow on Opus quietly costs several times what the same workflow costs on Sonnet or Haiku, and you will not notice until the bill arrives. The pin is the fix, and it is one line.
When I Delegate vs. When I Stay in the Main Thread
Delegation is a tool, not a reflex. I reach for a subagent when one of three things is true: the task produces bulky output that should not live in my main window, the task is genuinely independent and can run on its own, or I want an honest second opinion from an instance that has not been anchored by the rest of my conversation. That last one matters more than people expect — a fresh agent reviewing a change has not watched me talk myself into a bad decision, so it catches things the main thread has gone blind to.
I stay in the main thread when delegating would cost more than it saves. The clearest case is the one-shot read: if a single Read answers the question, a subagent that spins up, reads the same file, and returns is pure overhead. The main thread was about to do that work anyway. Conversational turns and trivial one-file edits belong in the main session, full stop.
When I do delegate, I batch. Three related questions become one subagent with all three in the prompt, not three separate agents. The fixed per-agent overhead and the overlapping file reads compound fast, and a single well-scoped agent answering all three is cheaper and usually sharper than three agents each loading the same context.
Parallel Subagents for Big Sweeps
The place subagents really earn their keep is a big sweep — work that decomposes into independent pieces. A multi-file audit, a broad search across naming conventions, a batch of status checks: launch them in one message and they run concurrently instead of one after another. Wall-clock time drops to the slowest single agent rather than the sum of all of them.
Each agent in the fan-out runs blind to the others, which is a feature, not a bug. When no single search angle will surface everything, several agents each searching a different way will find more between them than one agent grinding through sequentially. This is the same tool-use and fan-out thinking that shows up when you build an agent rather than use one — I wrote about that side of it in my post on building an AI agent that manages my blog, where the Model Context Protocol turns the same pattern into a product.
The Involuntary Floor Underneath
Subagents and model pinning are voluntary. They help only when I remember to reach for them, and "remember to" is a weak foundation for anything that matters. The durable half of my setup is involuntary: Claude Code hooks that run on every tool call and cannot be skipped, no matter what the model or I happen to be focused on.
The distinction that does the work is block versus advise. A PreToolUse hook can deny an action before it runs; a PostToolUse hook can inject a note after the fact and let things proceed. I block the non-negotiable, data-safety things — reading secret or credential files, destructive git commands like a blanket git add, a force-push, or a hard reset — because those are never something I want a model to do "helpfully." Everything softer is advisory: the hook leaves a note rather than stopping the work, so the floor protects without nagging me on every commit.
The policy itself lives in the repo's rules file, which keeps it reviewable in version control next to the code it governs rather than buried in someone's local config. And I keep the whole thing minimal on purpose: a layer goes in only when real friction demands it. One always-on floor that blocks the genuinely dangerous handful of actions beats a sprawling pile of half-used automation that everybody learns to click past.
Pitfalls
- Spawning an Opus subagent for cheap lookup work. This is the most common waste in the whole setup. If the agent is searching or summarizing, pin it to Sonnet or Haiku — Opus reasoning is doing nothing for a grep.
- Letting the main session accumulate stale context across unrelated tasks. When you finish one thread of work and start something unrelated, clear or compact. Otherwise every later turn pays to reprocess context that has nothing to do with what you are now doing.
- Treating subagent output as a human message. A subagent's return is data, not a chat reply. Keep its prompt scoped so the result is something you can act on directly, not prose you then have to read and re-summarize yourself — which would defeat the entire point of delegating.
How to Verify the Setup Pays Off
You do not need instrumentation to confirm this is working; you need to watch two things. First, the model indicator and the cost per turn before and after you move a class of work — exploration, summarization — onto pinned, cheaper agents. The per-turn cost on that work should drop visibly. Second, a simple behavioral check: a "find where X is used" task should now come back as a summary, not as twenty files loaded into your main transcript. If your main session is still filling up with raw file content, the delegation is not actually happening and something in your agent descriptions needs tightening.
What I Would Not Do
- Route everything through subagents. Conversational turns and trivial one-file edits belong in the main thread. Delegation has overhead; spending it on work the main session was going to do anyway is a net loss.
- Leave every agent on the default Opus model "to be safe." That is exactly how a search-heavy workflow quietly costs five times what it should. "To be safe" is a cost decision in disguise, and it is usually the wrong one.
- Build a sprawling library of overlapping agents. A few sharp, well-scoped agents beat a drawer full of near-duplicates you can never remember the boundaries of. When two agents do almost the same thing, the dispatcher cannot pick well and neither can you.
Final Thoughts
The win here is not "more agents." It is keeping the main context window lean and paying Opus prices only for Opus-grade work. Two pinned helpers, a tight tool allow-list, a clear sense of when delegation actually pays, and an involuntary floor underneath the whole thing — that is the entire setup, and it is deliberately small.
You can see how these habits play out in a real codebase in my Blogger Agent project, and read about the same tool-use thinking from the other side — building an agent rather than using one — in my post on the Blogger Agent build. For more about my work, check out my bio.

Software engineer building AI-powered products and the guardrails that make AI-assisted development safe to ship. Web3 frontend at LimeChain. Based in Sofia, Bulgaria.