How I Use Claude Code
The workflow I settled into after building a B2B SaaS with Claude Code as my primary development tool — planning discipline, context management, and what I'd tell someone starting out.
I’ve been using Claude Code as my primary development tool while building a B2B SaaS platform Cusflux. This is the workflow I settled into – what I do, why, and what I’d tell someone starting out. Boris Tane’s post covers similar ground and is worth reading alongside this.
The Core Workflow
The principle: never let Claude write code until you’ve reviewed and approved a written plan.
Don’t use Claude Code’s built-in plan mode for this. It doesn’t persist after the session, you can’t annotate it inline, and you can’t edit it in your own editor. Write a plan.md file instead. It’s a real artifact in your project that survives /compact, survives session restarts, and can be pointed to at the start of any future session to restore context instantly.
My sessions look like this: one long session from research through finalized plan, then short focused sessions per task during implementation.
What Claude Already Knows Before You Type Anything
Claude Code is a harness around a Claude model. The model has no ambient awareness of your project — it only knows what’s been assembled into the context window for that session. Understanding what’s in there, and what isn’t, shapes how you reason about everything else.
At session start, the context window contains:
- System prompt — harness instructions and permissions
- CLAUDE.md — your global
~/.claude/CLAUDE.mdand projectCLAUDE.md, both loaded in full every session - Auto memory — the first 25KB of
MEMORY.mdif it exists (written and managed by Claude Code itself, not by you) - Environment info — current working directory, platform, git state
- MCP tool names — schemas are deferred until a tool is actually called
That’s it. Everything else (e.g., your codebase, your schema docs, your plan) doesn’t exist to Claude until it explicitly reads it. File contents only enter the context when Claude calls the read tool. Every file it reads stays in context for the rest of the session, even if never referenced again, and that’s the largest driver of context growth during a session.
This is why context discipline matters, and why what goes into CLAUDE.md deserves more thought than most people give it.
Discuss Trade-offs Before Annotating
Boris’s annotation cycle is: Claude writes plan → you add inline notes → Claude updates → repeat. I add a step before annotating: I ask Claude to argue the alternatives first. Before writing notes into the plan, I ask Claude to compare approaches and explain the trade-offs. Not to make the decision but to surface things I might not have considered. This is especially valuable for decisions that seem straightforward but have non-obvious downstream consequences.
When planning a Stripe billing integration, for example, I knew I wanted an event-driven approach but wasn’t immediately certain which events to anchor on. Before annotating the plan I asked Claude to compare building around checkout.session.completed vs. customer.subscription.* events — idempotency characteristics, race condition risks, replay behaviour. That conversation surfaced the right answer. The annotation I then wrote into the plan was precise because I’d already thought it through out loud with Claude.
The pattern: use Claude as a thinking partner during planning, then annotate with confidence. The “don’t implement yet” guard stays throughout. The discussion doesn’t change that.
Keep CLAUDE.md Small
Project CLAUDE.md alone accounts for roughly 1,800 tokens at session start — before you’ve typed anything, before any file reads. A bloated one compounds that cost across every session, including ones where most of its content is irrelevant.
My rule: CLAUDE.md contains only things that are true forever and apply to every session. Architecture principles. Code style constraints. Things like: don’t use any types, run the type checker continuously, use this commit message format. Hard rules with no exceptions.
Everything else (e.g.,feature context, API behaviour, business rules, data models) lives in purpose-built documentation: a Functional Specification Document and per-domain API schema docs (e.g., billing_schema.md). At the start of a session I point Claude at whatever’s relevant:
read
billing_schema.mdin depth before we start
Claude gets exactly the context it needs for the task at hand. Nothing more. The schema docs are also living artifacts — Claude helps draft and update them as the system evolves, and they serve as the source of truth for everyone working on the codebase, not just Claude.
This matters when coordinating with other engineers. Versioned spec docs prevent silent divergence — two people implementing the same concept differently because they had different mental models. The docs make the architecture legible to everyone, and they keep Claude’s behavior consistent across sessions without inflating the context window.
A 500-line CLAUDE.md that documents every architectural decision in the project is not a good Claude Code setup. It’s a documentation failure dressed up as an AI workflow.
Cross-Session Drift
Claude Code does persist memory between sessions — through MEMORY.md, which it writes and manages automatically, and through CLAUDE.md which loads every session. So it’s not starting from zero. But general project memory isn’t the same as specific context. If you don’t explicitly point Claude at billing_schema.md at the start of a session, it may propose something that contradicts what’s documented there — not because it forgot the project exists, but because it hasn’t read that specific file yet.
The failure mode is subtle: Claude proposes something architecturally wrong at the start of a new session, before it’s read deeply into the relevant docs. It won’t argue. It just proposes. And if you’re moving fast, it’s easy to miss.
In my experience this only happened at session starts, not mid-session once Claude had read the relevant files. The fix is always the same: point it to the specific doc and ask it to reconcile. It corrects immediately.
Your session-opening prompt matters. Don’t say “let’s continue implementing X.” Say “read billing_schema.md and plan.md first, then we’ll continue.” Thirty seconds at the start of a session prevents almost all of this.
End to End
- Research
Ask Claude to read the relevant codebase and docs deeply, write findings to
research.md. Review it. Correct misunderstandings before moving on. - Discuss Before annotating, ask Claude to compare approaches and surface trade-offs. Make your call.
- Plan
Ask Claude to write
plan.mdwith a detailed implementation plan: approach, code snippets, file paths. Add a granular todo list before implementation starts. - Annotate
Open
plan.mdin your editor, add inline notes: corrections, constraints, rejections, domain knowledge. Send Claude back to update it. Repeat. Say “don’t implement yet” every time. - Implement “implement it all. mark tasks complete as you go. don’t stop until everything is done. run the type checker continuously.”
- Correct Terse corrections during implementation. Revert and re-scope when something goes wrong rather than patching a bad direction.
By the time you reach step 5, every decision has been made. Implementation should be boring. That’s the point.