Using Cursor and Claude Code as a Salesforce IDE
The Salesforce Extension Pack was reindexing SObject definitions for the third time that morning, and I was watching a spinner instead of writing code. That was the day I stopped treating the Salesforce IDE as a fixed thing you inherit. Over the following months I rebuilt my whole editing setup around Cursor and Claude Code, and I haven't gone back to stock VSCode for day-to-day Apex since.
This isn't a story about abandoning the Salesforce tooling. The sf CLI is still the engine. The Apex Language Server still does the heavy lifting on completion and go-to-definition. I deploy the same metadata I always did. What changed is the editor sitting on top of all that, and the fact that a good chunk of my typing now happens through an agent that reads the codebase before it writes a line.
The Editor Is Not the Point
Cursor is a fork of VSCode. Claude Code is a terminal agent. The sf CLI is the thing that actually talks to your org. If you keep those three facts straight, the setup makes sense; if you conflate them, you'll fight it.
I run Cursor as the editor because it's VSCode underneath, which means every Salesforce extension, keybinding, and setting I already relied on still works. On top of that I keep Claude Code open in the integrated terminal for the multi-step work — read these three classes, write the handler, deploy it, run the test, tell me what failed. Cursor's inline completion is good for the next fifteen characters. Claude Code is for the next fifteen minutes.
The mistake people make is expecting the AI layer to replace the platform tooling. It doesn't. The Apex Language Server is what gives you accurate symbol resolution against your org's actual schema. No language model reconstructs that from context reliably. The AI writes; the language server checks. You want both.
Getting the Apex Language Server to Behave in Cursor
This is the part nobody warns you about, so here's the honest version. Cursor doesn't pull extensions from Microsoft's marketplace — it uses Open VSX. The Salesforce Extension Pack is published there, so it installs, but the Apex Language Server is fussier than the marketplace version and it will sit there doing nothing if two things aren't right.
First, it needs a real JDK. Not whatever happens to be on your PATH — a specific Java 11 or 17 install, pointed at explicitly. I set it in the workspace settings.json:
{
"salesforcedx-vscode-apex.java.home": "/Users/shubham/.sdkman/candidates/java/17.0.10-tem",
"salesforcedx-vscode-core.retrieve-test-code-coverage": true,
"editor.formatOnSave": true
}
Second, the completion database. Apex autocomplete against your custom objects and fields comes from a local SObject cache, not the language server guessing. After authenticating the org you run SFDX: Refresh SObject Definitions from the command palette, which generates the .sfdx/tools/sobjects folder. Skip that step and every custom field shows up as an error even though the code is fine. I've watched more than one developer conclude the whole setup was broken when the actual problem was an empty cache.
Once those two things are in place, Cursor behaves exactly like VSCode with the extensions, plus the AI. That's the whole trick — you're not replacing the Salesforce tooling, you're wrapping it.
The Context File Does the Heavy Lifting
The single biggest lever on output quality is the context file. Claude Code reads a CLAUDE.md at the project root before it does anything; Cursor reads .cursorrules. I keep both, with the same content, because I switch between the two and I don't want the behaviour to drift.
This file is where you encode the conventions that a new contractor would otherwise learn by having a pull request rejected. Mine looks something like this:
# Project conventions
- SFDX source format. All metadata lives under `force-app/main/default`.
- One trigger per object, delegating to a handler. Never put logic in the trigger.
- New Apex classes are `with sharing` unless there is a documented reason not to.
- Test classes sit next to the class, named `<Class>Test`, and assert behaviour, not coverage.
- SOQL goes in a selector class, never inline in a handler.
## Deploy rules
- Default target org is the `dev` sandbox alias. Never deploy without an explicit `-o` flag.
- NEVER run a deploy against the `prod` alias. If prod is needed, stop and ask.
- Run the relevant test class after every deploy and paste the result before moving on.
The value of this file is that it turns the generic assistant into one that writes your org's Apex. When I ask it to scaffold a new trigger, it produces the thin trigger and the handler that follows the framework I document elsewhere, because I told it that's the pattern. Without the file, it invents its own structure — usually a reasonable one, occasionally the exact anti-pattern I've spent years removing from orgs.
I treat the context file as living documentation. Every time I catch the AI making the same wrong assumption twice, I add a line. Over a few weeks it stops making that mistake, and the file doubles as onboarding for the humans.
Closing the Loop with the CLI
The reason this setup earns its keep is that the agent can close the loop itself. It writes the class, deploys it, runs the test, reads the failure, and fixes it — without me copying error text back and forth. That only works because the sf CLI is scriptable and Claude Code can run it.
The loop, spelled out, is three commands:
# after the class is written or edited:
sf project deploy start -o dev -d force-app/main/default/classes/OrderTriggerHandler.cls
sf apex run test -o dev -t OrderTriggerHandlerTest -r human -w 10
sf org open -o dev -p /lightning/setup/ApexClasses/home
I tell the agent to run the first two after any change and to stop only when the tests pass. The -w 10 matters — it waits up to ten minutes for the async test run and returns the result inline, so the agent actually sees whether it worked rather than firing and forgetting.
This is the difference between AI as an autocomplete and AI as a colleague who checks their own work. I've written before about the actual prompt workflow I run for Apex — the context-first prompting, the tasks where it's a clear win and the ones where it isn't. The IDE setup in this article is the substrate that makes that workflow fast. The prompts are the technique; the closed CLI loop is the machinery.
One rule I hold firm: the loop deploys to a sandbox or a scratch org, never to production. The IDE is for building and validating. Production changes go through the pipeline, for the same reasons I've argued in my take on Salesforce CI/CD — deployments should be boring, auditable, and reproducible, and an agent running sf from my laptop is none of those things.
The Day It Almost Deployed to Production
I learned that last rule the hard way. On one engagement I'd been doing a quick data fix in production earlier in the week, and to save typing I'd run sf config set target-org to point the default at the prod alias. Then I forgot.
A couple of days later I was heads-down in the same project, told Claude Code to "deploy the updated handler and run the tests," and it did exactly what I asked — sf project deploy start with no -o flag, which resolves to the default org. The default org was production. It got as far as the deploy confirmation before I registered the org name in the output line and killed it. Maybe two seconds of margin.
Nothing broke. But it was close enough that I rewrote how I work. The NEVER deploy to prod line in the context file came from that morning. I also stopped setting production as a default target for anything, ever — if I need to touch prod, I type the full -o prod every time, deliberately, so it's a conscious act and not a leftover setting.
I'll be honest about the fix, though: it's not bulletproof. It relies on the agent honouring the instruction and on me reading the target line before I hit enter. Across maybe 40 client deploys since, it's held, but it's a guard rail made of discipline, not one enforced by the platform. That's still on my list to harden with a proper pre-deploy hook. For now it works because I'm paranoid, which is a load-bearing dependency I'm not thrilled about.
When I Still Open Plain VSCode
The setup isn't universally better, and pretending otherwise would be dishonest. There are jobs where I close Cursor and open stock VSCode, or drop the AI entirely.
Anything touching security-sensitive Apex, I write by hand. The agent will happily add Security.stripInaccessible and sharing checks, and it'll look right, but CRUD/FLS enforcement is exactly where I don't want plausible-looking code I didn't reason through myself. Retrieval-heavy debugging is another one — when I'm chasing a production issue through logs and I need to hold the whole call chain in my head, a chatty agent generating suggestions is noise, not help.
And there's a real cost to the AI layer being persuasive. It writes code that reads well and compiles clean, which makes it easy to approve without the scrutiny I'd give a junior developer's pull request. The failure mode isn't the AI writing obvious rubbish; it's the AI writing subtly-wrong code confidently enough that I nod it through. I've caught myself doing that. The counter is boring and manual: I review AI diffs harder than human ones, precisely because they look finished.
So the setup is a daily driver, not a religion. Most of the time Cursor and Claude Code get me from a ticket to a tested, deployed class faster than any environment I've used in fifteen years on the platform. Some of the time the right tool is a plain editor and my own head. Knowing which is which is the actual skill — and if you want a second pair of eyes on where that line sits for your team, that's the kind of review I do.
The old setup made me wait on a spinner while the tooling caught up to me. The new one waits on me while I decide what's worth shipping. I know which problem I'd rather have.
Liked this?
New essays in your inbox when I publish. No cadence, no spam.
You might also like
How I Use Claude Code to Write Apex 5x Faster
The actual workflow I run for AI-assisted Apex development — what AI handles well, what it gets wrong, and the prompts that survive code review.
Read →Using Local AI Models for Salesforce Development
Cloud AI is off the table at regulated Salesforce orgs. Here is how I run local models with Ollama for Apex and SOQL, the hardware, and the honest limits.
Read →How AI Changes the Salesforce Consulting Model
The economic shifts AI is bringing to Salesforce consulting — what's getting cheaper, what's getting more valuable, and what the agency model looks like now.
Read →