sfpm
Open source · MIT

Turbocharge your Salesforce development.

sfpm turns your Salesforce project into a real pnpm workspace, not just a workflow styled after one. Dependency-ordered builds, caching so nothing builds twice, and a package.json per package, so wiring in your own build tools is a pre or post hook away, not hand-rolled glue.

sfpm build
Animated terminal demo: sfpm build resolves dependency order across the core, lwc-utils and billing packages, skips already-cached builds, and reports progress until the build completes.

sfpm build. Dependency order resolved, cache hits skipped.

The problem

Stop hand-rolling the build order.

A handful of packages, a hand-maintained install order, and a cd into each one to run its own build before you can deploy anything. Or: one command.

zsh
$ cd packages/core && npm run build
$ cd ../lwc-utils && npm run build
$ cd ../billing && npm run build
$ sf project deploy start -p packages/core
$ sf project deploy start -p packages/lwc-utils
# …and keep the order straight
sfpm build
$ sfpm build core lwc-utils billing -v my-devhub
✔ corecached
✔ lwc-utils2.1s
✔ billing1.4s
→ 2 built · 1 skipped
Features

Built like the tooling you already use.

Dependency-ordered builds

sfpm reads your package graph and builds and deploys in the right order. No hand-maintained install lists.

Caching that skips the work

Unchanged packages are never rebuilt. Change a leaf, rebuild the leaf. Everything upstream stays cached.

CI that's just config

GitHub Actions for build, install and deploy. 'Deploy only what changed' falls out of an ordinary task graph, not a bespoke script.

Source-driven

Move work out of the org and into source.

Org-driven development leaves metadata mutating inside a shared org, hard to version and easy to conflict. sfpm pushes you toward modular packages that build and deploy from source, which is a far more tractable surface for CI, for code review, and for coding agents. Each package carries its own package.json, so the project itself becomes a real pnpm workspace: Turborepo, changesets, and the rest of the JS tooling ecosystem apply directly, not only the parts sfpm reimplements.

How it works

Project setup.

No account required. Install, configure, pull an org, and ship a package. The full walkthrough, flags, and CI setup live in the docs.

1

Install

Published to npm.

$ npm install -g @b64hub/sfpm-cli
2

Configure

Global settings live in sfpm.config.ts: plain TypeScript, loaded directly, no build step. Each package's own package.json drives its config; sfdx-project.json is generated from that and kept only for compatibility with other sf tooling.

# sfpm.config.ts is plain TS, loaded directly via jiti
$ sfpm package create --name my-package --type unlocked --devhub my-devhub
# (re)generates sfdx-project.json
$ sfpm project sync
3

Pull an org

pool fill keeps a pool of scratch orgs or refreshed sandboxes warm in the background (cron or CI). pool fetch claims one instantly, in seconds rather than the hours a cold org create or sandbox refresh can take.

sfpm pool fetch
Animated terminal demo: sfpm pool fetch claims a pre-provisioned scratch org, dev-pool-3, from the dev-pool pool in about a second, instead of waiting minutes to hours for a cold org create or sandbox refresh.
4

Build and deploy

One command builds in dependency order with caching. Deploy works the same way.

$ sfpm build my-package -v my-devhub
$ sfpm deploy my-package -o my-sandbox

Full walkthrough in the docs →

Read the docs. Ship a package.

Install takes a minute. The quickstart takes five.