How to Push Code to Production with Visual Studio Code & Salesforce CLI?


Hello Trailblazers! 👋
After years of working as a Salesforce Deployment Expert and handling lakhs of deployments—yes, lakhs—across sandboxes and production environments, I’ve learned one thing for sure: a clean, efficient deployment process makes all the difference. And when it comes to modern Salesforce development, there’s hardly a better combo than VS Code + Salesforce CLI (SF CLI).
In this article, I’ll share my go-to method for deploying changes to Salesforce Production directly from VS Code using only Salesforce CLI. Whether you're a budding developer or a seasoned release manager, this guide will walk you through everything from setup to best practices—with tips I’ve picked up from countless successful (and a few not-so-successful!) deployments.
Pre-requisites
Before we dive into the commands and test levels, let’s get our basics covered.
VS Code: Make sure you have the latest version installed.
Salesforce CLI: Update to the latest version for compatibility and new features.
Salesforce Project: Your VS Code should already have a Salesforce project set up. The metadata you want to deploy should be inside this project.
Authorized Org: Ensure you’ve authorized with your production org. Want to know “How to Authorize a Salesforce Org”?
Apex Test Coverage Levels
When deploying to a Salesforce Production org, understanding how Apex test coverage works is absolutely crucial—especially if your deployment includes Apex classes or triggers. Salesforce enforces a minimum of 75% code coverage for Apex code in production. However, the way you choose to run tests during deployment can make or break the process.
Here’s a breakdown of all the deployment test levels you can use with Salesforce CLI (sf CLI) and when to use which one, based on your scenario:
1. NoTestRun — Quickest, for Non-Apex Metadata
Use this when:
Your deployment does NOT include any Apex classes or triggers.
You're only deploying configuration metadata like Flows, Objects, Validation Rules, Custom Fields, etc.
Command example:
sf project deploy start -d force-app/main/default/flows/AccoutAutomation.flow-meta.xml
Note: No unit test is run, no code coverage check is done. Perfect for non-code metadata changes.
2. RunAllTestsInOrg — For Full Coverage & Final Validation
Use this when:
You want Salesforce to run ALL test classes, including:
Test classes from your org's source code
Test classes inside installed managed packages
Ideal for final validations before actual deployment.
Important Notes:
Slowest test level. Can take hours depending on your org size.
Salesforce prefers the local version of a test class if it exists in both your local repo and production.
Use this level with --dry-run to validate first, then use the Quick Deploy ID for actual deployment.
Best Practice:
Validate with RunAllTestsInOrg
, and then Quick Deploy to production using the generated job-id.
Command examples:
sf project deploy start -x manifest/package.xml -l RunAllTestsInOrg --dry-run
➡️ Once validated, deploy using:
sf project deploy quick --job-id 0Af0x000017yLUFCA2
3. RunLocalTests — All Tests Except from Managed Packages
Use this when:
You want to exclude test classes from managed packages.
Your org has a lot of installed packages that unnecessarily increase deployment time during test runs.
Important Notes:
Still time-consuming for large orgs, but faster than
RunAllTestsInOrg
.Still follows the same logic: if a test class exists locally and in production, Salesforce uses the local version.
Again, best used for validation first, followed by quick deployment.
Command examples:
sf project deploy start -d force-app -l RunLocalTests --dry-run
Then:
sf project deploy quick --use-most-recent --target-org my-prod-org
4. RunSpecifiedTests — When You Know What to Target
Use this when:
You're deploying Apex classes or triggers.
You want to run only specific test classes that cover those components.
Key Considerations:
You are responsible for ensuring that the specified test classes cover at least 75% of the code being deployed.
The specified test class must exist in your local repo or production. If it's in both, the local version is prioritized.
Great for fast, targeted deployments of specific functionality.
Common Pitfall: Missing or insufficient test coverage will cause deployment to fail, so choose test classes wisely.
Command example:
sf project deploy start -x manifest/package.xml -l RunSpecifiedTests -t AccountsTest1 AccountsTest2
These options give you incredible flexibility to adapt to your team’s needs, deployment timelines, and production org complexity. Picking the right test level strategy not only speeds up the process but reduces risk significantly.
In my experience of managing lakhs of deployments, the most effective method is:
✅ Validate using
RunAllTestsInOrg
orRunLocalTests
💡 Use --dry-run first to catch issues in advance
⚡ Deploy quickly using the Quick Deploy ID
Trust me—it'll save your nights and weekends during release windows!
Deployment Methods Using SF CLI
Salesforce’s new sf CLI (successor to sfdx
) makes deploying metadata from your local project to any Salesforce org much more flexible and efficient. Based on your deployment scenario and the type of metadata, you can choose from a variety of methods. Here’s a comprehensive breakdown of how to deploy using the SF CLI.
1. Quick Deploy Using Deployment ID
Once you've validated your metadata with one of the test levels that generate a Quick Deploy ID (RunAllTestsInOrg
, RunLocalTests
, or RunSpecifiedTests
), you can save hours of deployment time by pushing the changes using that ID.
Command examples:
# Using specific job ID
sf project deploy quick --job-id 0Af0x000017yLUFCA2
# Use the most recent validated deployment automatically
sf project deploy quick --async --use-most-recent --target-org my-prod-org
2. Deploy Specific Component(s)
This is the simplest and quickest way to deploy when you're working with just one or few components, such as a Flow, Apex class, LWC, or Permission Set.
Command examples:
# Deploying a single flow
sf project deploy start -d force-app/main/default/flows/AccoutAutomation.flow-meta.xml
# Deploying a custom field and a flow
sf project deploy start -d force-app/main/default/objects/Account/fields/Account_Website__c.field-meta.xml force-app/main/default/flows/AccoutAutomation.flow-meta.xml
# Deploying an Apex class
sf project deploy start -d force-app/main/default/classes/AccountHandler.cls -l RunSpecifiedTests -t AccountTest1 AccountTest2
💡 Pro Tip: Always double-check the path and metadata name. This method is great for hotfixes or small admin changes.
3. Deploy Using Folder Path
When you’ve made changes to multiple files inside one or more folders, this method helps you push everything in one go.
Command examples:
# Deploy all Apex classes:
sf project deploy start -d force-app -l RunLocalTests
# Deploy entire Account object and all Apex classes
sf project deploy start -d force-app/main/default/objects/Account force-app/main/default/classes -l RunAllTestsInOrg
# Deploy all components:
sf project deploy start -d force-app -l RunLocalTests
# Deploy all Account fields and all Flows
sf project deploy start -d force-app/main/default/objects/Account/fields force-app/main/default/flows
4. Deploy Using package.xml
This method gives you precise control over what gets deployed. Create a package.xml
and keep it in a manifest folder. Then:
Command examples:
# Deploy the components of package.xml wih RunSpecifiedTests
sf project deploy start -x manifest/package.xml -l RunSpecifiedTests -t AccountsTest1 AccountsTest2
# Deploy the components of package.xml wih RunLocalTests
sf project deploy start -x manifest/package.xml -l RunLocalTests
Use this when you want to deploy multiple types of metadata (Apex, Flows, Objects, etc.) defined in package.xml.
5. Deploy a Destructive Changes Package
Place both destructiveChanges.xml and a blank package.xml in a folder (e.g., builds/delete).
Then run:
sf project deploy start --metadata-dir builds/delete -l RunSpecifiedTests -t DummyClass
📌 Important:
Backup before deletion.
Resolve dependencies.
Use a dummy test class if Apex isn’t involved.
Best Practices for Smooth Deployments
🧪 Validate First, Deploy Later
Always validate using RunAllTestsInOrg
or RunLocalTests
first, get a quick deployment ID, and then deploy. Saves time and avoids surprises.
📦 Use Sandboxes
Always deploy to a sandbox (UAT/QA) before production. This helps catch issues early.
🔒 Take Backups
Before deploying especially destructive changes, take a metadata backup of affected components.
✅ Ensure 75% Code Coverage
Apex code must meet Salesforce’s 75% coverage requirement. Use tools like sf apex run test or pre-deployment checks.
Conclusion
Pushing code to Salesforce production via VS Code and Salesforce CLI is not only efficient but also puts full control in your hands. No clicks, no waiting, and no surprises—just clean, command-driven deployments.
I’ve executed lakhs of deployments using this exact method and can confidently say: once you get the hang of it, you’ll never go back to change sets!
So go ahead, try it out, and make deployments your strong suit. If you found this article helpful, don’t forget to like, share, and drop your thoughts in the comments. Let’s grow together as a community. 💬
Happy Deploying! 🚀
Subscribe to my newsletter
Read articles from Pushkar Raj Sindal directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Pushkar Raj Sindal
Pushkar Raj Sindal
Hi there! I'm a Salesforce & DevOps Consultant with over 7 years of experience in the IT industry, specializing in DevOps solutions for Salesforce. From setting up robust CI/CD pipelines to optimizing deployment strategies, I’m passionate about building scalable and efficient development workflows. I love sharing practical insights and writing about Salesforce DevOps, development best practices, and automation tools.