The Salesforce CLI (command line interface) is the cornerstone of Salesforce development, and like any other tool, it evolves with time. This post is the second of a two-part blog series on sf (v2), the new and improved Salesforce CLI. In Part 1, we took a look at what’s new with sf (v2) and, in this final part, we’ll explore the new sf-style commands and flag patterns and share how you can migrate from sfdx-style commands and flags based on our experience with sample apps. While the migration may seem intimidating at first glance, we’ll share some tips on how to ease the transition.

Meet sf-style commands

If you’ve been using the CLI for some time, you probably started noticing a number of warnings on the commands that you frequently use, such as this one:

These changes are the result of the ongoing work on the Salesforce CLI Unification that started several releases ago (more details in the first part of this series).

Since then, whenever you install the Salesforce CLI, you now get the two executables (sfdx and sf). You can use either of these executables as most commands are interoperable, but we recommend that you start using sf in your daily work to prepare for the future.

Because sf covers more than just core Platform development, it offers a new simplified command taxonomy that reflects a typical developer’s workflow rather than Salesforce brands, products, or features.

A practical example of this is the sf org create command. With this new command, the intent is made clearer: you call the same command base with scratch, sandbox, shape, snapshot, or user, whereas in sfdx you had to use a mix of different commands (force:org:create, force:user:create) and flags (--type=scratch or --type=sandbox) for the same result.

Another neat feature of sf is that it ships with more visual and interactive commands, such as the creation of orgs with the ability to resume long-running operations in case of time out.

A screenshot of the sf scratch org creation command that shows the dynamic progress UI

Migrate to the sf executable

Besides simply switching the name of the executable from sfdx to sf, there are a number of changes that apply to CLI commands when upgrading your projects. The Salesforce CLI documentation provides a good overview of these changes, but we’ll highlight the ones that impacted us during the upgrade of our sample apps.

Common sfdx commands and their sf equivalents

First of all, the force topic has been removed from most commands, which is good news as it shortens commands. The other major change is that topics, commands, and subcommands, which were previously separated by colons as in sfdx force:org:list, are now separated with spaces, such as in sf org list.

Looking more closely at the commands that we use daily when working on sample apps, we applied the following changes:

Legacy sfdx Command Equivalent sf Command Migration Comments
sfdx force:org:delete -p -u recipes sf org delete scratch -p -o recipes The scratch subcommand needs to be added.
The target org flag changes from -u to -o.
sfdx force:org:create -s -f config/project-scratch-def.json -d 30 -a recipes sf org create scratch -d -f config/project-scratch-def.json -y 30 -a recipes The scratch subcommand needs to be added.
The “assign default org” flag changes from -s to -d.
The scratch org duration flag changes from -d to -y.
sfdx force:source:push sf project deploy start This is a significant change, but the new command works for all project formats (source or metadata).
Previously, you needed distinct commands.
sfdx force:user:permset:assign -n recipes sf org assign permset -n recipes The topic changes from user to org and the order of the sub commands changes.
sfdx force:data:tree:import -p data/data-plan.json sf data import tree -p data/data-plan.json
sfdx force:org:open -p lightning/n/Hello sf org open -p lightning/n/Hello
sfdx force:apex:test:run -c -r human -w 20 sf apex test run -c -r human -w 20

If you’re looking for other commands, the CLI documentation provides a full list of sfdx commands with their sf equivalents. Whenever replacing a command, make sure you review its flags for changes, especially if you use the short-form (single character) flags (-o instead of --target-org for example). You can run any command with the -h or --help flag to get their description.

Automate some of the migration with regular expressions

ℹ️ Edit from July 27, 2023: instead of a regular expressions you can use a migration script as documented here.

ℹ️ Edit from August 3, 2023: you can refer to the sf-style command migration guide for additional tips.

When we looked into migrating our sample apps projects, we knew that we would need to automate some of the process as there were close to 1700 references to sfdx in 200+ files. To get the most accurate results here, make sure you add a space after sfdx in your search term and exclude the node_modules folder from your search, like we did here:

Screenshot showing VS Code search results for “sfdx” across all sample app projects

Starting with a search is a good first step. It helps you realize that you’ll have to migrate your commands in a couple of places, such as:

  • Continuous integration scripts
  • Local development scripts
  • Documentation

You can then go further by experimenting with a Regular Expression (RegEx) search and replace in VS Code. This approach is a quick way to kick off the migration. It works well for search, but it isn’t perfect for replacement as some commands require manual updates. In any case, always test the outcome of your changes before pushing them to production.

Start by running this RegEx search and replace:

Note the use of three capture groups enclosed by parentheses in the search expression and represented by dollar signs followed by a number in the replace expression. Capture groups allow you to dynamically retain certain values (words such as topics, commands, and subcommands in our case) while making changes in the rest of the line (replacing colon separators with spaces in our case).

If you’d like to learn more about this RegEx or others, I recommend that you check out regex101.com as it provides an explanation of the syntax and a playground for testing expressions.

Here’s an example of the input and output in VS Code of the above expression (don’t forget to activate RegEx mode as indicated by the red arrow):

Screenshot of VS Code showcasing the regex search and replace

You’ll note that this first round of search and replace isn’t perfect as you get some extra space characters in the replaced text. You can easily fix this by running a second RegEx search and replace operation like this:

Once you run this last RegEx, there are still a couple of manual changes that you’ll need to operate. As we saw earlier in the command equivalence table, here are the key things to keep in mind:

  • Some commands use different topics and subcommands. For example, sf user assign permset is incorrect: user needs to be replaced by org.
  • Some flags need to be changed. For example, sf org create scratch -s -f config/project-scratch-def.json -d 30 -a recipes is incorrect: the -d flag needs to be replaced by -y and -s flag needs to be replaced by -d.

Fortunately, most of these changes aren’t too hard to apply and you can migrate fairly quickly to the sf-style commands. We’ll leave you with a GitHub diff view that summarizes all of the changes that were necessary to migrate one of our sample apps.

Closing words

That’s a wrap for this short overview of the migration from sfdx-style commands to the sf-style commands. You had a glimpse at the benefit of the sf executable and its new syntax. We hope that you’ll benefit from our migration experience and our tips when upgrading your projects.

Resources

About the author

Philippe Ozil is a Principal Developer Advocate at Salesforce where he focuses on the Salesforce Platform. He writes technical content and speaks frequently at conferences. He is a full-stack developer and enjoys working on DevOps, robotics, and VR projects. Follow him on Twitter @PhilippeOzil or check his GitHub projects @pozil.

Get the latest Salesforce Developer blog posts and podcast episodes via Slack or RSS.

Add to Slack Subscribe to RSS