Why AI tools changed how I think about development

I used to approach AI tools as autocomplete on steroids. Copy in a function, get a suggestion, maybe keep it, maybe not. That's not how they're most useful.

The shift for me happened when I stopped thinking of Copilot and Claude as code generators and started treating them as a second dev on the project — one that can hold context, draft implementations, and flag edge cases, but still needs me to review, shape, and take responsibility for everything that ships.

That mental model completely changed how I structure my prompts, when I reach for which tool, and how much time I actually save.

The two-tool setup and when to use each

I use two AI tools consistently:

  • GitHub Copilot — inline, within VS Code, for anything code-adjacent: completions, refactors, quick explanations, writing tests, boilerplate generation
  • Claude — for thinking through architecture, reviewing larger blocks of logic, writing first drafts of things I'll then edit, and handling anything requiring nuanced English prose

They're not interchangeable. Copilot is fast and contextual — it sees your file, your cursor, your recent edits. Claude is better at reasoning through problems when I paste in the relevant context myself.

Rule of thumb: if I can describe the task in one line of inline comment and Copilot fills it in correctly, I use Copilot. If I need to explain what the code is doing before asking for help, I use Claude.

How I structure my prompts to get useful output

Vague prompts produce vague code. The pattern I've settled on for non-trivial requests:

  • Context first — what file, what component, what framework, what constraints
  • Intent second — what the code should do, not how to write it
  • Constraints third — no new dependencies, keep it typed, match the existing naming convention
  • Output format — just the function, no explanation unless I ask for one

Here's a real example of how I'd phrase a request for a Svelte component:

Context: SvelteKit 2, TypeScript, no additional packages.
The file is src/lib/components/Toast.svelte.
We have a toast notification system using a writable store.

Task: Write a `dismiss(id: string)` function that removes a toast
by id from the store, with a 300ms fade-out transition.

Constraints:
- Use existing $toasts store from $lib/stores/toasts.ts
- No animation library — CSS transition only
- TypeScript strict mode

Compare that to "write a dismiss function for toasts." The structured version gets working output on the first try almost every time. The loose version requires three follow-up rounds.

The validation step that most people skip

The biggest mistake I see with AI-assisted development: running the generated code without reading it.

AI models confidently write code that compiles and passes type checks but has logic errors, security issues, or doesn't account for edge cases that are obvious from context the model didn't have. This is especially true for anything touching authentication, data mutation, or async error handling.

My rule: I never commit AI-generated code I haven't read line by line. The review catches maybe 20–30% of outputs needing correction, but those are the 20–30% that would have caused bugs or regressions.

The workflow I follow:

  1. AI generates the draft
  2. I read every line before running it
  3. I mentally trace the execution path once
  4. I run it, check the output matches intent
  5. I write or review the relevant test if it's a pure function

This adds maybe two minutes to each AI-assisted task. It has saved me from shipping broken code more than once, and it keeps me genuinely understanding the codebase I'm working in.

Real patterns I use daily

1. Comment-driven generation in Copilot

I write a detailed comment above a function I'm about to write, then let Copilot complete it. The comment forces me to think through what I actually want before the code exists, which improves both the prompt and the result.

// Debounces a search input by 400ms.
// On each input event, clears previous timer and sets a new one.
// Calls onSearch(value) only after user stops typing.
// Handles cleanup on component unmount.
function useDebouncedSearch(onSearch, delay = 400) {
  // Copilot completes this correctly from the comment above
}

2. Claude for architecture decisions

When I'm starting a new feature that touches multiple files or has a non-obvious data flow, I paste the relevant existing code into Claude and ask it to propose two or three implementation approaches. I don't take one wholesale — I read through the trade-offs and pick the structure that fits, then write the code myself or let Copilot help with the boilerplate.

3. AI for writing tests I'd otherwise skip

Let's be honest: test coverage on time-pressured projects suffers. With AI tools, writing unit tests for a pure function takes 90 seconds instead of 10 minutes. I paste the function into Claude, ask for edge-case-focused tests in Vitest, review and adjust them, done.

This has meaningfully improved my test coverage on recent projects without significantly adding to development time.

4. Code review with Claude before PR

Before submitting a PR on anything non-trivial, I paste the diff into Claude and ask: "What could go wrong? What did I miss? Are there security concerns?" It catches things I've genuinely overlooked — missing null checks, race conditions in async code, accessibility gaps in HTML I wrote quickly.

What AI still can't do well

After a year of daily use, here's where I consistently hit the ceiling:

  • Understanding your codebase holistically. Even with good context in the prompt, the model doesn't feel the accumulated weight of architectural decisions. That pattern recognition still lives in your head.
  • Debugging subtle state issues. Anything involving reactive state across multiple components, timing, or side effects — AI is often confidently wrong. I debug these manually.
  • Matching exact project style and conventions. It approximates. You have to correct drift constantly, or better, give it a detailed style guide as part of the context.
  • Making product judgment calls. "Is this UX pattern the right one?" — AI will give you an answer but it won't be accountable to your users.

Being clear about these limits is what makes the rest of the workflow reliable. I know where AI helps me go faster, and I know where I need to slow down and think myself.

The actual time savings — honest numbers

People overstate AI productivity gains because they measure the best cases. Here's a more honest breakdown from my experience:

  • Boilerplate and scaffolding: 60–70% faster. This is where AI is genuinely transformative.
  • Writing tests: 50–60% faster.
  • Debugging: Neutral to slightly negative if I over-rely on it. AI suggestions lead me down wrong paths often enough that I lose more time than I save.
  • Code review and spotting issues: 30–40% of the value I now get from AI, and it was the last thing I started using it for.
  • Architecture and design decisions: Useful for exploring options quickly, but the thinking time stays the same.

Net: I ship roughly 30–40% more per unit of time on most frontend projects. That's not a number from a marketing page — it's what I've observed across real production work over the past year.

Setting up Copilot for a project

A few things that made Copilot dramatically more useful once I set them up properly:

  • A .github/copilot-instructions.md file with project conventions, naming patterns, and the tech stack — Copilot reads this and adapts suggestions accordingly
  • TypeScript strict mode enabled — typed context means better, safer completions
  • Keeping files focused and well-named — Copilot uses filename and surrounding code as context; a 600-line mixed-concern file gives worse suggestions than two focused 300-line files
  • Using comments aggressively before complex blocks — even when I don't need Copilot to complete the code, writing the comment sharpens what I'm about to write

The instruction file trick: I write per-project AI instructions the same way I'd write an onboarding guide for a new junior dev. Tech stack, conventions, what we don't do, and why. The AI follows it; real devs appreciate it too.

One principle that makes everything else work

Stay in the driver's seat. The developers I've seen get the most out of AI tools treat them as tools, not oracles. They push back when output is wrong. They read before they run. They take ownership of everything in the codebase regardless of what generated it.

AI-assisted development that works is still development. It's faster development, more thoroughly explored development — but the judgment, the accountability, and the craft are still yours.