Prompt Mastery Intermediate
The quality of your prompts determines the quality of Claude Code's output. Master the art of writing specific, actionable prompts that produce correct results on the first attempt.
The Golden Rules of Prompting
-
Be specific about files and functions
Always reference the exact file path and function name when possible. Instead of "fix the login," say "fix the
validateCredentialsfunction insrc/auth/login.ts." -
Use the "Edit X to do Y" pattern
The most effective prompt structure is: "Edit [specific file/function] to [desired behavior]." This gives Claude a clear target and goal.
-
Provide examples of desired output
Show Claude what success looks like. If you want a specific format, give an example.
-
Reference existing patterns
"Follow the same pattern used in
src/routes/users.ts" tells Claude to match your codebase's conventions. -
Break complex tasks into steps
Instead of one massive prompt, break it into sequential requests. Claude performs better on focused tasks.
Real-World Prompt Examples
1. Bug Fixing
# Bad > fix the bug # Good > In src/utils/date.ts, the formatDate function returns "Invalid Date" when passed > a Unix timestamp in seconds (e.g., 1700000000). It expects milliseconds. Fix it > to handle both seconds and milliseconds. Add a test case to tests/utils/date.test.ts.
2. Feature Implementation
# Bad > add pagination # Good > Add cursor-based pagination to the GET /api/posts endpoint in src/routes/posts.ts. > Follow the same pattern used in src/routes/comments.ts. The response should include > nextCursor and hasMore fields. Update the PostRepository in src/repos/post.repo.ts > to accept cursor and limit parameters. Default limit: 20, max: 100.
3. Refactoring
# Bad > clean up the code # Good > Refactor src/services/payment.ts to extract the Stripe-specific logic into > a separate src/services/stripe.adapter.ts file. Create a PaymentProvider > interface so we can swap Stripe for another provider later. Keep all existing > tests passing.
4. Test Writing
> Write comprehensive unit tests for src/services/user.service.ts using Jest. > Cover: createUser (valid input, duplicate email, missing fields), > updateUser (partial update, non-existent user), deleteUser (soft delete behavior). > Mock the UserRepository. Follow the test style in tests/services/auth.service.test.ts.
5. Code Review
> Review the changes in the last commit (git diff HEAD~1). Focus on: > 1. Security issues (SQL injection, XSS, auth bypasses) > 2. Performance problems (N+1 queries, missing indexes) > 3. Error handling gaps > Do NOT suggest style changes. Only flag real bugs and security issues.
6. Documentation
> Add JSDoc comments to all exported functions in src/utils/. Include @param > and @returns tags with types. For complex functions, add a @example block. > Don't add comments to internal/private functions.
7. Migration
> Migrate all API route handlers in src/routes/ from Express to Fastify. > Start with src/routes/auth.ts as a reference. Keep the same URL paths and > HTTP methods. Use Fastify's schema validation instead of our custom middleware. > Do one file at a time and run tests after each.
8. Git Operations
> Review the git log for the past week. Create a changelog grouped by: > Features, Bug Fixes, and Improvements. Use the conventional commits format. > Skip merge commits and CI-related commits.
9. Performance Optimization
> The /api/dashboard endpoint in src/routes/dashboard.ts takes 3 seconds to load. > It makes 5 sequential database queries. Optimize it by: > 1. Running independent queries in parallel with Promise.all > 2. Adding caching for the stats query (5 minute TTL) > 3. Adding a database index if needed for the slow queries
10. Error Handling
> Add comprehensive error handling to src/services/payment.ts: > - Wrap all Stripe API calls in try/catch > - Create custom error classes in src/errors/ (PaymentFailedError, CardDeclinedError) > - Log errors with context (userId, amount, stripe error code) > - Return user-friendly error messages (don't expose Stripe internals)
11-15. Quick Prompt Templates
# 11. Type Safety > Add TypeScript types to all 'any' types in src/services/. Use strict types, no 'any'. # 12. API Endpoint > Create a new POST /api/webhooks/stripe endpoint following the pattern in src/routes/webhooks/github.ts # 13. Database Query > The query in src/repos/analytics.ts line 34 is slow. Add an index and optimize the JOIN. # 14. Configuration > Add environment variable validation at startup in src/config.ts. Fail fast if required vars are missing. # 15. Cleanup > Find and remove all unused imports and dead code in src/utils/. Run tests to make sure nothing breaks.
When to Use One-Shot vs Interactive
Use -p (One-Shot) |
Use Interactive Mode |
|---|---|
| Simple, well-defined tasks | Exploratory tasks ("help me understand...") |
| Automated scripts and CI/CD | Multi-step refactoring |
| Quick fixes you can describe precisely | Tasks requiring back-and-forth discussion |
| Batch processing multiple files | Debugging complex issues |
| Generating commit messages | Architecture decisions |
Anti-Patterns to Avoid
- "Fix everything" — Too vague. Claude will either do too little or too much.
- "Make it better" — Better how? Be specific: faster, more readable, more secure.
- Mega-prompts — Don't ask Claude to do 10 unrelated things in one prompt. Break it up.
- No file references — Always mention which files to work on. Don't make Claude search blindly.
- Ignoring existing patterns — Tell Claude to follow your codebase's conventions.
- Not testing — Always ask Claude to run tests or verify its changes.
Practice Makes Perfect
Take a task you've been meaning to do and write the most specific prompt you can. Include file paths, function names, desired behavior, and test verification. In the next lesson, you'll learn how to maximize Claude's understanding of your codebase through context management.
Next: Context Management →
Lilly Tech Systems