Skip to content

AIExplore

How to Get Better Code from Claude

Get higher-quality code from Claude with specs, test-first prompts, acceptance criteria, and review checklists that catch issues before merge.

Most code quality issues from Claude are not Claude's fault — they are brief quality issues. Vague asks produce working-but-fragile code. Specific asks with test expectations and edge cases produce code that survives review.

Write the spec before the code

Tell Claude what the code should do in terms of inputs, outputs, edge cases, and constraints before asking it to write anything. This is the single most effective quality lever.

Bad

Write a function to validate email addresses.

Better

Write a TypeScript function validateEmail(input: string): boolean.
It should accept standard email formats and reject obvious invalids.
Include edge cases.

Best

Write a TypeScript function:
validateEmail(input: string): { valid: boolean; reason?: string }

Acceptance criteria:
- Accept: standard user@domain.tld formats
- Accept: plus addressing (user+tag@domain.tld)
- Reject: missing @ symbol, missing domain, double dots in domain
- Reject: empty string, whitespace-only input
- Return a reason string for every rejection

Edge cases to handle:
- Leading/trailing whitespace (trim before validation)
- Very long local parts (>64 chars)
- Unicode in local part (reject for now, flag as future consideration)

Do not use a regex longer than one line. Prefer step-by-step string checks.
Write the function, then write 8-10 test cases covering the acceptance criteria.

The best version works because Claude has a type signature, acceptance criteria, specific edge cases, an implementation constraint, and a testing requirement. The output is reviewable against the spec.

Ask for tests alongside the implementation

When you ask Claude for code without tests, you lose your fastest way to verify correctness. Ask for tests in the same prompt, or write the tests first and ask Claude to write code that passes them.

Here are 6 test cases for a parseCSVRow function:
[PASTE TEST CASES]

Write the implementation that passes all 6 tests.
Language: TypeScript. No external dependencies.
After writing the code, walk through each test case and explain why it passes.

Pre-merge review checklist

Before merging any Claude-generated code, run through this checklist. You can also ask Claude to self-review against it.

  • Does the code match the spec — all acceptance criteria covered?
  • Are edge cases handled or explicitly documented as not handled?
  • Is error handling consistent with the rest of the codebase?
  • Are there any hardcoded values that should be constants or config?
  • Does the diff stay within the agreed scope — no surprise refactors?
  • Can you explain every line? If not, ask Claude to explain before merging.
  • Does the code introduce security risks (SQL injection, XSS, secret exposure)?

Requesting incremental improvements

If the first version works but needs refinement, ask for one improvement at a time.

The function works but has two issues:
1. It does not handle the case where [EDGE CASE].
2. The error messages are too generic — make them specific to each failure mode.
Fix only these two issues. Do not refactor anything else.

Common code quality mistakes

  • Accepting code that works for the happy path but ignoring edge cases
  • Not specifying the return type — Claude picks whatever seems reasonable
  • Asking for a full refactor in one prompt instead of incremental changes
  • Skipping the self-review step — Claude can catch its own issues when asked

Related reading: /blog/how-to-use-claude-for-coding for the basic coding brief and /blog/how-to-debug-and-review-code-with-claude for debugging patterns.

Related articles