← Back to blog

How I Use Claude Code to Write Apex 5x Faster

·7 min read

I write Apex faster than I did three years ago. The platform hasn't gotten dramatically more productive. The IDE hasn't fundamentally changed. What's changed is I now run an AI-assisted workflow using Claude Code as a daily driver, and the boring stuff that used to take hours takes minutes.

I'm going to walk through the actual workflow — not the demo version, the version that survives code review at a financial services org. I'll cover what AI handles well, what it consistently gets wrong, and the specific prompt patterns that produce code I'd ship.

The Setup

I run Claude Code (Max 5x plan, ~$100/month) in a terminal alongside my IDE. The Salesforce CLI (sf) is installed and authenticated to my dev sandbox and a couple of scratch orgs. Source format SFDX project, standard structure.

Claude Code reads the entire project's metadata when needed — Apex classes, custom objects, custom metadata types, Flow definitions. That context is the thing that makes the workflow work. It's not generating code from a blank slate; it's generating code that fits the patterns and conventions already in your codebase.

Cursor and VSCode with Copilot work similarly for the inline editing flow. I prefer Claude Code for the multi-step tasks where I want it to read files, write files, run tests, and iterate. Different tools, same workflow shape.

The Tasks Where AI is Clear Win

These are the ones where I genuinely move 3-5x faster:

Apex test classes. Test data factories, positive cases, negative cases, governor limit edge cases. AI generates the obvious cases at speed. I add the edge cases that come from production scars — the ones that come from 15 years of seeing what actually breaks.

A typical prompt:

"Generate test class for AccountTriggerHandler.afterUpdate. Include positive case (new annual revenue triggers tier recalc), negative case (no revenue change skips recalc), bulk case (200 records), and governor limit assertion (must use less than 50 SOQL queries). Use TestDataFactory.createAccount where available."

What I get back is usually 80% right. The remaining 20% is fixing assertions that are too lenient, edge cases the AI didn't think of, and refactoring to match my project's testing conventions.

Bulk refactors. "Convert all System.debug calls in this folder to use Logger.debug from our logging utility." "Add with sharing to every Apex class missing it." "Update all SOQL queries in this directory to use bind variables instead of string concatenation."

These take hours by hand. AI does them in minutes, with a clear diff to review. The 5x figure for me is mostly driven by these tasks — they're the ones I'd otherwise procrastinate forever.

Documentation generation. Markdown documentation for an Apex class — describing public methods, parameters, return types, side effects, and example usage. Class header comments. Method-level Javadoc-style annotations. Even README-style docs for entire packages.

Writing docs by hand is a slog. Writing docs from existing code is something AI does well, and the result is consistent enough to actually maintain.

Boilerplate for new patterns. When I'm building a new trigger handler that follows the framework I've documented, AI scaffolds the class, the test class, and the custom metadata bypass record in 30 seconds. I edit the actual logic. The plumbing is free.

The Tasks Where AI is Mixed

SOQL generation. Surprisingly capable, occasionally dangerous. AI knows the SOQL syntax, knows about selective queries, knows about governor limits. What it doesn't know is your specific data shape — whether External_Id__c is actually indexed in your org, whether your Account.Industry field has 5 picklist values or 50.

I treat AI-generated SOQL the way I treat AI-generated regex: fine for a starting point, but verify against actual data before shipping. The SOQL antipatterns I've covered before are the ones I specifically watch for in AI output.

Flow generation via metadata XML. Flows can be defined in metadata XML files, and AI can write reasonable Flow XML. But the platform's UI is the source of truth for Flow design — what AI generates is usually a starting structure that I open in Flow Builder and finish manually. Useful for the skeleton; not useful for the polish.

Apex tests for legacy code. If the legacy code was written without testability in mind — heavy static state, no dependency injection, tight coupling to specific record IDs — AI can't write good tests for it. The tests it writes will pass coverage but won't catch real bugs. The fix is refactoring for testability first; AI helps with that refactor too, but it's a longer loop.

The Tasks Where AI is Currently Bad

Architecture decisions. Ask AI whether to use a Flow or an Apex trigger for a specific use case, and you'll get a balanced essay about trade-offs that doesn't actually help. The decision depends on context — your team's skills, your org's existing patterns, your maintenance posture, your release cadence. AI doesn't know any of that without being told, and even when told, it tends to hedge.

I make these decisions myself and use AI for execution, not direction.

Anything involving security review judgement. AI can generate Apex that's technically CRUD/FLS-safe — it'll add Security.stripInaccessible calls and check Schema.sObjectType.X.isAccessible(). Whether the generated code passes a Salesforce security review is a different question, and the answer depends on review-team subjectivity that AI can't predict.

For AppExchange-bound code, I write the security-sensitive parts myself and use AI only for the surrounding plumbing.

Subjective code style. What constitutes "clean" code is project-specific. AI defaults to a generic style. If your codebase uses fluent builders and AI generates static utility methods, the diff in code review will be noisy even when the logic is correct. I tell it the project's style explicitly when it matters.

The Prompts That Actually Work

A few patterns I've settled on:

Always give it the calling context. "Generate processOrder(List<Order> orders)" gets generic code. "Generate processOrder(List<Order> orders) called from OrderTriggerHandler.beforeInsert after the recursion guard but before the validation pass — must use bulkified SOQL, no DML, no callouts" gets code that fits.

Always give it the output expectations. "Generate Apex test for ContactDeleteValidator" produces something. "Generate Apex test for ContactDeleteValidator with: at least one negative case using Test.startTest/stopTest, governor limit assertion of <50 SOQL, exact assertion that the validation rule fires for the specific message text, and bulk case with 200 records each having the trigger condition" produces something I can ship.

Always make it read the existing code first. Before generating, I tell Claude Code "read force-app/main/default/classes/AccountTriggerHandler.cls and force-app/main/default/classes/AccountTriggerHandlerTest.cls first. Match the patterns there." This is the difference between a draft I rewrite and a draft I edit.

What I'd Skip

AI-generated comments inside the code. AI loves comments. Most of them describe what the next line does, which I can already see. I strip them in review unless they explain a non-obvious why.

AI-generated commit messages. They're fine but they sound like AI. I'd rather write a one-line message that captures the intent than a five-line message that captures the diff.

Asking AI to generate the test plan from a user story. It'll make up scenarios that aren't in the story. I write the test plan; AI writes the test code.

The Honest Limits

The "5x faster" figure is real for the specific tasks where I use it. It's not real for everything. The hard parts of Apex — figuring out the right architecture, debugging a production issue, understanding why a specific picklist value is breaking an integration — those don't get faster. They might get slightly faster because the boring parts of the work are out of the way, but the cognitive load is the same.

What changes is the ratio. I used to spend 60% of my coding time on boilerplate, tests, and refactoring grunt work. That's down to maybe 15%. The rest goes to the parts that genuinely require thought — and the parts where I can help clients with the things AI can't shortcut.

The goal isn't to write more Apex. It's to write the right Apex faster, and have more time left for the design decisions AI doesn't help with.

Liked this?

Get one Salesforce insight per week. No spam.