Pukar Ghimire
Back home

Writing

How I work with Claude Code

I use Claude Code as the engineering half of a very small product team. I decide what gets built and when; it does the heavy lifting in between. This is how that works in practice, and where it falls short.

TL;DR

  • I run work through explicit phases: research or audit, then a PRD, ADR or plan, then my approval, then build, review and commit. Claude stops at each gate until I say go.
  • Documents come before code. Most features start as a written plan or decision record, so there's an audit trail and a clear target.
  • Inside an approved phase I give it wide autonomy: short directives, then long stretches of multi-file changes, mostly driven through the shell, with verification and reviewer agents along the way.
  • One branch per feature, with PRs and ADRs. I expect that workflow to be followed without reminders.
  • Visual work is the exception. I slow down and iterate by eye over several rounds of screenshots before any tests or reviews run.
  • The main frustrations: it sometimes jumps ahead of my sign-off, misjudges scope, and its first-pass code and design choices often need another round. Long sessions and sandbox quirks add friction too.

A gated pipeline

The core of how I work is that I own the decision points and Claude owns the execution. I set the phase I'm in (research, audit, PRD, plan, build, review, commit) and expect it to stop at the end of each one.

A typical feature looks like this: I ask for an audit or a plan, it comes back as a list of numbered findings or steps, and I reply with the ones I want built, something like “do H2 to H5, S1 and U1.” Only then does code get written. After the build comes verification, review, and finally a commit and push.

I don't micromanage how something is implemented. I do guard whether and when it gets implemented. That split lets me move fast without losing control over the direction of the product.

Documents before code

Most non-trivial work starts with a written artifact: a product requirements doc for a new tool, an architecture decision record for a change with trade-offs, or an implementation plan that breaks a feature into steps. Having them first does a few things for me:

  • I can disagree with the approach before anything is built.
  • The decision is recorded next to the code, so I, or a future session, can see why something is the way it is.
  • Later sessions pick up from the document instead of re-deriving context from the codebase.

I treat PRDs as living guidance rather than hard rules. When planning a second version of a product, the original “out of scope” list is a starting point, not a constraint.

Research and audits first

Before committing to a direction I usually commission some kind of evidence: a UX audit built from real screenshots of the app, a pre-launch checklist, an abuse-prevention review, a cloud provider comparison, or competitor and app-store review research for my target market.

The output is always something I choose from. I want findings ranked by severity and effort, not a pile of changes already made. Because the evidence comes first and I pick the fixes, the work stays aimed at what actually matters for the people using the product.

Letting it run

Once a phase is approved, I step back. My messages tend to be short directives, and Claude spends long autonomous stretches working through them. Most of that work happens through the shell: builds, tests, git, database queries, and checking the app in a browser. Edits span many files at once rather than one-off tweaks.

A few habits make that autonomy safe:

  • Verify before calling it done. Lint, type-check, tests and end-to-end runs happen before anything is finished.
  • Reviewer agents. For bigger changes, separate agents review the diff for correctness and security, and their findings get fixed.
  • Browser checks. UI changes get looked at in a real browser, not assumed to work because the build passed.

I also chain a lot into a single session: merging branches, cleaning up a repo, building a feature, then starting a whole new site, back to back. “Verify, review, commit” is probably my most common closing instruction.

Branches, PRs and ADRs

Every feature gets its own branch, a pull request, and usually an ADR or a PRD addendum. Claude handles the mechanics: branches, commit messages, PRs, rebases, and conflicts such as database migrations that collide between branches.

This is a big reason multi-file changes land as reviewed, tested commits instead of a tangle of half-finished edits. It also keeps the history readable when I come back to something weeks later.

Iterating on visual work

Design is where I slow down. For themes, landing pages, animated illustrations, auth screens and mobile layouts, I iterate in tight rounds by eye. Claude makes a change, checks it in the browser, shows me a screenshot, and I say what to adjust.

I hold back reviewers, tests and commits until I've signed off on the design. A full review of a version I'm about to throw away is wasted effort.

I know what I want when I see it, and I'd rather Claude ask than guess. When it does guess, I push back on choices I don't like, whether that's an oversized button, a decorative graphic that doesn't fit, or animation where it isn't needed.

What I use it for

The same approach holds across very different kinds of work:

  • Full-stack product work on a construction management app for contractors: auth, client invites, contracts with PDF generation, an admin console, document attachments and more.
  • Infrastructure and launch: infrastructure as code, deployment guides, maintenance mode, offline support, SEO, and diagnosing and fixing a live outage.
  • Research and marketing: competitive research, marketing briefs, and programmatic promo videos with voiceovers in more than one language.
  • Side projects: this site, an education data atlas with interactive charts and maps, a job-application tracker browser extension, and sanitized public versions of private repos.

Limitations and hindrances

It isn't friction-free. These are the issues I ran into most often.

Acting before approval

The most common one. Claude would sometimes treat an audit, a research task or a skill invocation as permission to start building. It began implementing fixes during audit-only phases, scaffolded a project with a styling approach I hadn't chosen, and launched UI reviewers before I'd looked at a feature. Each time I had to stop it and roll back.

Misreading scope

Requests were sometimes read as bigger, smaller or more rigid than I meant. Asking it to check that existing migrations ran cleanly turned into building a new migration branch. Saying something seemed broken led to new UI being added, when the feature worked and I'd been using it wrong. Loose guidelines in a PRD were treated as hard limits.

First-pass bugs and design misses

First drafts of code often needed another round: lint failures, type errors, and occasionally real issues like race conditions or data written to the wrong place, which review then had to catch. On the design side, its first instincts frequently missed my taste and had to be reworked or removed.

Long sessions hitting limits

I tend to chain many tasks into one long session, and those sometimes ran out mid-task, leaving reviewer fixes or a later phase unfinished.

Environment friction

Some time went to the environment rather than the work: sandbox restrictions around Docker, commit signing and network calls, dev servers that didn't pick up server-side changes, and long-running processes that timed out in the background. Research was also limited by sites that block automated access, which pushed it toward other sources.

What I changed because of them

Most of these are fixable with a bit of upfront structure:

  • State the gate up front. “Audit only, don't edit anything until I pick” or “show me screenshots and wait” prevents most of the jumping ahead.
  • Write the rules down. Approval gates, scope expectations and styling preferences belong in the project's instructions file, so they don't need repeating every session.
  • Turn rituals into commands. Repeated sequences like verify, review, commit and push work better as a reusable skill with the gates built in.
  • Automate the cheap checks. Running format and lint after every edit catches first-pass mistakes before I see them.
  • Checkpoint long sessions. A running progress file and a commit after each finished task mean a new session can resume cleanly if one gets cut off.

The overall lesson: Claude Code is most useful when I'm clear about where the decision points are, and generous with autonomy everywhere else.