If you've been doing everything in the Salesforce UI — deploying through change sets, testing in the developer console, managing orgs through the browser — the CLI does most of it faster and with less friction.
The Salesforce CLI is called sf (formerly sfdx). You install it on your machine, open a terminal, and run commands. It authenticates to your Salesforce orgs and communicates directly with the Salesforce APIs — no browser, no clicks.
Download the CLI from developer.salesforce.com/tools/sfdxcli. After installation, verify it's working:
sf --version
If you use VS Code, the Salesforce Extensions pack gives you autocomplete and integrated org management. The CLI itself works from any terminal on any operating system.
Before you can do anything, connect to an org:
sf org login web --alias dev-sandbox
A browser window opens. Log in to your Salesforce org. The CLI stores the credentials. All subsequent commands use the alias — a short name instead of the long username string.
sf org list # list all connected orgs
sf org open --target-org dev-sandbox # open in browser
The primary CLI deployment command:
sf project deploy start --target-org dev-sandbox
It reads your local project directory (the force-app folder by default) and deploys to the target org. The key advantage over change sets: error output is specific. Instead of a vague "component it depends on" message, you get the exact field name, object name, and validation rule that caused the failure.
The opposite operation — pulling metadata from a source org down to your local project:
sf project retrieve start --target-org dev-sandbox
This captures existing org configuration — flows, custom objects, profiles, permission sets — and brings it into your local project structure. Retrieve before deploy: always know what's in your project before you ship.
With source tracking enabled, sf project retrieve start only pulls what changed since your last sync. This is much faster than a full retrieve. Source tracking works by default in scratch orgs. For sandboxes, it needs to be enabled at the sandbox level.
A scratch org is a temporary Salesforce environment that spins up from a config file in under a minute:
sf org create scratch \
--definition-file config/project-scratch-def.json \
--alias my-scratch
The scratch org definition is a JSON file that specifies which Salesforce features the org should have. When you're done:
sf org delete scratch --target-org my-scratch
No cleanup. No lingering test data. No configurations affecting your next build. They're the Salesforce equivalent of a Docker container — disposable, reproducible environments.
Scratch orgs become powerful in CI pipelines: every pull request creates a fresh scratch org, deploys the branch, runs tests, and tears down. If tests pass on a clean org, you have high confidence in what you're shipping.
sf apex run
# Interactive mode — type Apex directly
sf apex run --file scripts/clear-queue.apex
# Run a file against a connected org
Common use cases: clearing stuck queue items, testing a utility method before embedding it in a class, resetting data to a known state during development. More useful more often than people expect.
sf apex run test \
--test-level RunLocalTests \
--target-org dev-sandbox
Returns pass/fail, coverage percentage, and specific failure messages inline. No developer console, no browser. This is what CI pipelines run to gate deployments.
sf data query \
--query "SELECT Id, Name FROM Account LIMIT 10"
sf data import tree --files data/sample-accounts.json
Query, import, export — all from the terminal. Useful for seeding scratch orgs with test data, exporting sample datasets, or running ad-hoc debugging queries.
sf plugins install @salesforce/sfdx-scanner
The CLI has a plugin system. Salesforce publishes official plugins — the code analyzer runs static analysis on your Apex without deploying. Third-party plugins exist for specific workflows. Check what's available before solving a problem manually.
The entire package lifecycle runs through the CLI:
sf package create --name MyPackage --type Unlocked
sf package version create --package MyPackage
sf package version promote --package 04t...
sf package install --package 04t... --target-org prod
Create, version, promote, install. If you're building anything beyond a single-org deployment workflow, unlocked packages and the CLI go together.
The Dev Hub is the org that manages scratch orgs and packages. Enable it in Setup → Dev Hub, then connect:
sf org login web \
--set-default-dev-hub \
--alias DevHub
All scratch org creation and package management flows through the Dev Hub. Typically your production org or a dedicated hub org.
sf generate class --name MyApexClass
# Creates MyApexClass.cls + test class
sf generate component --name MyComponent
# Creates LWC folder structure
Files start from the correct structure. Saves time and prevents common errors from manual file creation.
sf apex get log --target-org dev-sandbox
# Retrieve existing logs
sf apex tail log --target-org dev-sandbox
# Stream logs live as generated
Live streaming is useful when you're triggering a process and want to watch what happens in real time. More accessible than the debug log UI.
The first day with the CLI feels unfamiliar. You need to know the commands, you need aliases set up, you need your project structure in order.
After that, it becomes muscle memory. The speed difference versus doing everything through the UI compounds quickly. Two weeks in, going back to change sets and the developer console feels like a step backwards.