Salesforce Source-Driven Development and Scratch Org

Dhaval Heruwala
Mar 30, 2019 · 9 min read

This article is to provide hands-on experience with Salesforce DX and Scratch Org development.

Create Scratch Org

  1. Make sure you have the DevHub feature enabled
  2. download your source repo or create a new project using the command below
sfdx force:project:create -n MutualFundExplorer
  1. go to repo using change directory (cd) command
  2. Use the command below to create a scratch org
sfdx force:org:create -s -f config/project-scratch-def.json -a dreamhouse-orgsfdx force:org:create -s -f config/project-scratch-def.json -a GeoAppScratch
  • The -s option indicates that you want this scratch org to be the default org for this project.
  • The -f option is the path to the project scratch org configuration file.
  • The -a option, lets you refer to the org using its alias, GeoAppScratch, in future commands.

View the Configuration data for the scratch org:

sfdx force:org:display -u TempUnmanaged

Notice that the output provides the Instance URL, which is the My Domain value for the scratch org. You need this, along with the username and password, to install the package.

create password

sfdx force:user:password:generate -u TempUnmanaged

Launch the scratch org

sfdx force:org:open

Launch the scratch org with a specific page

sfdx force:org:open -p lightning/n/GIFter

Push your source metadata to Scratch Org

sfdx force:source:push

Assign the default user in the scratch org to Dreamhouse permission set

sfdx force:user:permset:assign -n Dreamhouse

or extract permission set

sfdx force:source:pull -u TempUnmanaged

Import Static Data

sfdx force:data:tree:import --plan data/sample-data-plan.json

login(connect with sfdx) to an existing org with web user password, -d is to make the org as default when you have many orgs connected

sfdx force:auth:web:login -d -a DevHub

give an alias, e.g. [errored with grant type not supported]

sfdx force:auth:web:login -r -a FullSandbox
sfdx force:auth:web:login -r -a DevSandbox

view all Dev org and currently connected org. Lists all authenticated orgs, including expired, deleted, and unknown-status scratch orgs.

sfdx force:org:list --verbose

the output of this command lists any org that you’re connected to, including Dev Hub, Trailhead Playgrounds, and scratch orgs. The (D) indicates your default Dev Hub org. If you see a (U), all CLI commands run against that username by default.

Delete a scratch org

sfdx force:org:delete-u

logout all orgs

sfdx force:auth:logout — all

Create a Salesforce DX Project

creates a project named geolocation on local

sfdx force:project:create -n geolocation


  1. create scratch org (command above) & Push your local source and metadata to a scratch org.
  2. Make any changes in scratch org
  3. Pull any changes you make in the scratch org back to your local project.
sfdx force:source:pull
  1. Sync this project with your VCS repo.
  2. a)create git repo

back to salesforce

sample data import export from scratch org.

first make a directory for data

mkdir data

import data to your local repo from scratch org. this is to help fellow developer to populate sample data in their scratch org

sfdx force:data:tree:export -q "SELECT Name, Location__Latitude__s, Location__Longitude__s FROM Account WHERE Location__Latitude__s != NULL AND Location__Longitude__s != NULL" -d ./data

After creating scratch, if you are planning to import data, assign permission

sfdx force:user:permset:assign -n Geolocation

if you or fellow developer ever need to import this sample data to their scratch org, use below command

sfdx force:data:tree:import --sobjecttreefiles data/Account.json

CLI to create an Apex class & Lightning component, refer this Trailhead.

Validate Your App

While you can absolutely use the same scratch org you’ve used during development to perform your testing, we recommend that you always start with a fresh scratch org. A fresh scratch org ensures you’ve properly externalized all your source from the org.

  1. Create a new scratch org:

sfdx force:org:create -f config/project-scratch-def.json -a GeoTestOrg

2. Push your local source and metadata to the scratch org:

sfdx force:source:push -u GeoTestOrg

3. Assign your permission set:

sfdx force:user:permset:assign -n Geolocation -u GeoTestOrg

4. Load your sample data into the org:

sfdx force:data:tree:import -f data/Account.json -u GeoTestOrg

5. Open your org:

sfdx force:org:open -u GeoTestOrg

6. Test the Account Locator tab, and verify that it works as expected. Click the App Launcher, then Account Locator.

Congratulations! You’ve successfully built and tested a new app with scratch orgs and the Salesforce CLI. Don’t forget to add everything to your VCS!

— — — -

Working with Package and Metadata api conversion

Retrieve the contents of the DreamInvest package into meta data api package to a subolder called mdapipackage

sfdx force:mdapi:retrieve -s -r ./mdapipackage -p DreamInvest -u TempUnmanaged -w 10

Convert the contents of the mdapipackage folder

sfdx force:mdapi:convert -r mdapipackage/

Deleting Scratch org

sfdx force:org:delete -u TempUnmanaged

Deploy the Converted App Using Metadata API

login to your test org / sandbox

sfdx force:auth:web:login -a MyTP

confirm the org is available

sfdx force:org:list

Convert Source to Metadata Format and Deploy

  • Create the project and scratch org
  • Install the DreamInvest unmanaged package
  • Create the appropriate permissions set
  • Extract the DreamInvest package source into your project
  • Convert the source, push it into a new scratch org and verify your work
  • Deploy the converted DreamInvest app using the Metadata API
  • Register your testing environment
  • Convert from source format to metadata format and deploy the DreamInvest app to your Trailhead Playground

— — -

Connected App

A connected app integrates an application with Salesforce using APIs. Basically, it enables your headless process to connect to the Dev Hub and execute Salesforce CLI commands.

Wire It All Together

Package Development

First of all, enable the following 2 features in Dev Hub.

  1. download repo

2. login or connect to your org using sfdx command

3. Create unlocked package

sfdx force:package:create --name dreamhouse --description "My Package" --packagetype Unlocked --path force-app --nonamespace --targetdevhubusername DevHub
  • --name is the package name. This name is an alias you can use when running subsequent packaging commands.
  • --path is the directory that contains the contents of the package.
  • --packagetype indicates which kind of package you’re creating, in this case, unlocked.

To list all the packages you created in your Dev Hub

sfdx force:package:list

Test package on Scratch Org

  1. create scratch org
sfdx force:org:create --definitionfile config/project-scratch-def.json --durationdays 30 --setalias MyScratchOrg -v DevHub

2. Install package in Scratch org

2.1 update package version in sfdx-project.json to next version. e.g. 0.1 to 1.0

2.2 Create Package version using command below, note that this is not creating package, it is next

sfdx force:package:version:create -p dreamhouse -d force-app -k test1234 --wait 10 -v DevHub
  • -p is the package alias that maps to the package ID defined in sfdx-project.json
  • -d is the directory that contains the contents of the package.
  • -k is the installation key that protects your package from being installed by unauthorized individuals.
  • It can take several minutes to create version

2.3 Use the package version alias to install the package version in the scratch org that you created earlier. (Don’t lose your patience)

sfdx force:package:install --wait 10 --publishwait 10 --package dreamhouse@1.0.0-1 -k test1234 -r -u MyScratchOrg

or below for no prompt and current scratch org

sfdx force:package:install --wait 10 --publishwait 10 --package GIFter@1.0.0-1 -k test1234 --noprompt

Note: The install command effectively replaces the force:source:push command

2.4 Launch your scratch org to see your package installed

sfdx force:org:open -u MyScratchOrg

2.5 search Installed Package in QuickFind

Note: you can now, make changes directly in the scratch org and pull down the updated metadata, then create a new package version.

3. Releasing Package

By default, packages are created Beta and you cannot install beta to prod

3.1 Promote the package version to release, ideally you release the package version only when you’re ready to install in a prod org

sfdx force:package:version:promote -p dreamhouse@1.0.0-1 -v DevHub

4 Install released Package version in an Org (Not just scratch org)

4.1 login to your Org using sfdx command

4.2 Install the pcakge version in Org (Trailhead Playground)

sfdx force:package:install --wait 10 --publishwait 10 --package dreamhouse@1.0.0-1 -k test1234 -r -u MyTP

On successful installation, you will get email

4.2.1 you may or may not need to assign the permission set

sfdx force:user:permset:assign -n GIFter -u MyTP

4.3 Open your Org (Trailhead Playground) and verify under installed apps

sfdx force:org:open -u MyTP

Note: add -p lightning/n/GIFter switch to launch specific page

Updating Unlocked Package

You are not always going to install a new package, that is just a one-time activity, most of the time you would be updating package. Here is how you can do that.

  1. Update versionName and increment versionNumber in sfdx-project.json
"versionName": "Summer '18 (new color)","versionNumber": "1.1.0.NEXT"

2. Create a package with updated source and the new version

sfdx force:package:version:create -p GIFter -d force-app -k test1234 --wait 10 -v DevHub

3. install test package in fresh scratch org

sfdx force:org:create -s -f config/project-scratch-def.json
sfdx force:package:install --wait 10 --publishwait 10 --package GIFter@1.1.0-1 -k test1234 --noprompt
sfdx force:user:permset:assign -n GIFter
sfdx force:org:open -p lightning/n/GIFter

4. Let’s install it to our Sandbox or TP (this will replace old package)

sfdx force:package:install -u DevHub --wait 10 --package GIFter@1.1.0-1 -k test1234 --noprompt
sfdx force:org:open -p lightning/n/GIFter -u DevHub


limit of active scratch org: 3, maximum creation in a day 6

Scratch org is for reuse, no wonder why there is 30 days sprint validity

Package is not like nuget or npm, package is made of many components where component is like a nuget or npm

sfdx commands are case sensitive

sometime while login command waits and never comes out, use ctrl + C to exit vs code long running command

You do not need a giant project to hold all the packages for your business unit. Just like .Net solution, you can have individual project of packages going to one big org

Org limit for a user:

sfdx force:limits:api:display -u

CI and CD
integrations test, build and deploy your project based on specifications stored in the repository.
code quality checking tools to dependency management,
and even automated security checks.
GitHub’s API and webhooks make it easy for new integrations.

Pipeline build

branch & commit

Create Lightning Web Component using VS Code

  1. Ctrl + Shift + P
  2. Create a SFDX Project SFDX: Create Project
  3. Authorize a Dev Hub SFDX: Authorize a Dev Hub
  4. Create a Scratch org SFDX: Create a Default Scratch Org
  5. Create a Lightning Web Component SFDX: Create Lightning Web Component
  6. Push to a Scratch org SFDX: Push Source to Default Scratch Org

Git Basics

Initialize and connect to the git repo

git init
git remote add origin <github ssh url>

check status

git status

Remove directory from git but NOT local

git rm -r --cached myFolder

Remove from both git and local

git rm -r myFolder

Add all files to the staging

git add -A

add an individual file to staging

git add .gitignore

commit with comment

git commit -m "remove .sfdx/ tracking"


git push origin master -f
git push origin master

list all branch with the current branch having * in front of it

git branch

create local branch

git branch my-own-branch

Switch to your own branch or master branch

git checkout my-own-branch
git checkout master

when you commit, it goes to branch.

to transfer from my-own-branch to remote

git push -u origin my-own-branch

pull master

git pull origin master

list merged branches

git branch --merged

merge the branch into master at local

git merge my-own-branch

push changes to master on remote

git push origin master

once branched, delete local branch / remote branch

local git branch -d my-own-branch

remote git push origin --delete my-own-branch

you can merge master into feature branch like this

git merge origin/master

Note: while resolving conflict, Open that file in your text editor, and look for the merge conflict markers. (<<<<<<<, =======, >>>>>>>)

Both branches’ versions of code are present — pick which code you want to keep and delete the other. Be sure to delete the merge conflict markers created by Git and save your changes.

you can also do automatic commit using command below while working on a big file

git add --patch

commit history, q to quit

git log

switch -10 shows most recent 10

visual graph

git log --oneline --graph

compare 2 commits

git diff 4e3dc9b 0cd75d4

As a general rule, you should only use git revert if the commit has been pushed to the remote.

You can use git commit --amend to make a modification to the last commit you made

Git has a git reset command that can help rewind the history

git difference between remote master and local master branch

`git diff master origin/master`


final version 1.0.0

git tag -a v1.0.0 -m “This is the final version” 

to view tag

git tag

to push tags

git push --tags

to delete tag locally

git tag -d v1.0.0

to push tag deletion to remote

git push origin :v1.0.0

git basics

Dhaval Heruwala

Written by

Enterprise Architect, Developer @ ECFMG. I like building things with great craftsmanship.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade