Package Manager
Package Manager in Salesforce DX is the tooling and command surface for creating, versioning, distributing, and installing packages, primarily second-generation packaging (2GP) but with continued support for first-generation managed packages.
Definition
Package Manager in Salesforce DX is the tooling and command surface for creating, versioning, distributing, and installing packages, primarily second-generation packaging (2GP) but with continued support for first-generation managed packages. The Package Manager features are exposed through the sf CLI's sf package commands and the underlying Salesforce DX project structure that defines what goes into a package. Package Manager is the foundation of the modern ISV development workflow and the increasingly common pattern of large enterprises packaging their own internal apps as unlocked or unmanaged packages for cross-org distribution.
The term encompasses both the developer-side tools (creating packages, building versions, promoting versions through testing environments) and the org-side install experience (installing a package, upgrading to a new version, uninstalling a package). The unified Package Manager surface replaced the older fragmented tooling (separate first-gen and second-gen commands, browser-based install URLs, change-set-based deployment) that made ISV development and large enterprise package management significantly harder than it should have been.
The packaging types Package Manager supports
Second-generation managed packages
2GP managed packages are the modern ISV distribution format. They support source-driven development (the package contents live in a Salesforce DX project structure backed by Git), versioned package releases, dependency declarations between packages, and a more predictable upgrade story for subscriber orgs. Package Manager creates a Package2 record in a Dev Hub org that anchors the package's identity, then builds Package Versions from the project source on demand. Each Package Version is installable by URL or CLI command and produces a consistent install experience across all subscriber orgs. The transition from first-gen to 2GP has been gradual since 2018, with most new ISV development now using 2GP exclusively.
Unlocked packages for internal apps
Unlocked packages are the second-gen format aimed at customer (non-ISV) use. They have the same build and install mechanics as 2GP managed packages but without the managed-namespace restrictions. The package contents remain visible and editable in the subscriber org, which suits internal-team apps where the building team is also the consuming team. Many large enterprises use unlocked packages to distribute internal apps (a common quote-to-cash framework, a shared customer-master enrichment service) across multiple business unit orgs while maintaining version control and consistent deployment. Package Manager treats unlocked packages identically to managed packages from a build perspective.
Dev Hub and the project structure
Every Package Manager operation requires a Dev Hub: a Salesforce org with the Dev Hub feature enabled that anchors all package definitions. The Dev Hub is typically a production org for ISVs or a dedicated administrative org for enterprises. The Salesforce DX project structure defines what goes into each package: source files (Apex, LWC, metadata XML) organized into packageDirectories that map to specific packages. The project's sfdx-project.json declares the packages, their versions, their namespaces (for managed), and their dependencies. The combination of Dev Hub and project structure is the developer's home base for everything related to package creation and management.
Build, version, and promotion
Creating a new package version follows a consistent sequence: sf package version create builds the version from the current project source, runs validation, and produces an unreleased version with a 04t Id. The version is then tested in a scratch org or sandbox install, and if it passes testing, promoted with sf package version promote to a released state. Released versions are immutable and installable in any subscriber org. The build process supports skipping validation for faster iteration during development, dependency resolution for packages that depend on other packages, and ancestor-version declarations for managed packages to control upgrade compatibility.
Installation and upgrade in subscriber orgs
Subscribers install a package version by URL (a unique install URL per version) or by CLI command (sf package install). The install process resolves dependencies, prompts for any required configuration (API access, IP restrictions, named user grants), and deploys the package metadata to the subscriber org. Upgrades follow a similar flow with sf package install pointing at a newer version; the package replaces the prior version's metadata while preserving any subscriber customizations the package design has allowed. Uninstalling a package removes all the package metadata cleanly, though any data created in package custom objects can be optionally retained.
Dependencies and dependency resolution
Packages can depend on other packages. A customer-facing AppExchange product might depend on a shared library package that the same ISV maintains. Package Manager handles dependency resolution during install: if the target package depends on a specific version of another package, the install process verifies that version is present in the subscriber org (or installs it first). Dependencies are declared in the sfdx-project.json with the dependent package's 04t Id and version. This dependency model is one of the biggest advantages of second-generation packaging over first-gen, where dependencies had to be manually coordinated through separate install URLs.
Package licensing and the LMA
ISV-distributed managed packages carry license metadata that controls how many users can access the package's features in each subscriber org. The License Management App (LMA), installed in the ISV's own org, tracks license usage across all customer installs and surfaces metrics about adoption, version distribution, and license utilization. Package Manager respects the license model during install: the package's license is provisioned to the subscriber org based on the ISV's contract with that customer. For unlocked packages (internal use), licensing is not enforced because the contents are not restricted. Understanding the licensing implications matters when choosing between managed and unlocked package types for a new distribution scenario.
CI/CD integration with Package Manager
Modern Salesforce development pipelines integrate Package Manager into the CI/CD flow. The typical pipeline runs on every push to a feature branch: validate the source against a scratch org, run all Apex tests, build a temporary package version, and report status back to the pull request. On merge to main, the pipeline builds a release-candidate version, promotes it to released, and deploys it to a UAT environment for stakeholder review. On approval, the same package version is installed in production. This source-to-release pipeline removes much of the manual coordination that legacy change-set-based deployment required, and the immutability of released package versions provides clear audit trails. Tools like GitHub Actions, GitLab CI, Jenkins, and Salesforce DevOps Center all support Package Manager workflows out of the box, with examples in the Salesforce documentation and the broader community. Teams that have not yet moved to a packaged deployment model should evaluate the migration as part of any DevOps modernization effort; the benefits in deployment reliability, audit, and team velocity are usually significant.
Create and distribute a package with Package Manager
Building a package with the modern Package Manager tooling follows a standard sequence from Dev Hub setup through version release. The walkthrough below covers a typical unlocked package scenario where an enterprise wants to distribute an internal app across multiple business unit orgs.
- Enable Dev Hub and set up the project
In the org that will serve as Dev Hub (typically the production org for ISVs or a dedicated admin org for enterprises), enable Dev Hub in Setup. Authorize the Dev Hub from the local Salesforce DX CLI (sf org login web). Initialize the project structure (sf project generate) with the appropriate packageDirectories. Add the package's source files to the right directory. Commit everything to source control before proceeding.
- Define the package and create the first version
Run sf package create to declare a new package in the Dev Hub, specifying the name, description, and type (managed or unlocked). Update sfdx-project.json with the package details and dependencies. Run sf package version create to build the first version. The command pushes source to a build scratch org, validates the package, and produces a 04t Id and install URL. Test the install URL in a clean scratch org to confirm the package installs correctly and behaves as expected.
- Test in sandboxes and iterate
Install the package version in one or more sandboxes representing the target subscriber environments. Run the standard testing for the application: unit tests, integration tests, user acceptance scenarios. Capture any issues, fix them in the source, and create new package versions iteratively. Each version is immutable once promoted, so most teams use unreleased versions during development and promote only the final candidates.
- Promote and distribute
Once a version passes all testing, run sf package version promote to mark it as released. Distribute the install URL to the subscriber orgs' admins, or have the central team run sf package install against each target org. Document the version in the org's package registry with the release date, what changed, and any subscriber-org configuration required. Schedule the subsequent version on a predictable cadence so subscribers know when to expect updates.
Required to anchor all package definitions and authorize the CLI for package operations.
The local project with packageDirectories, sfdx-project.json, and source files organized by package.
The command-line tool that runs all Package Manager operations.
Required on the Dev Hub for the user running package commands.
Required for tracking the package source over time. Git is the standard, with releases tagged to specific commits.
- Released package versions are immutable. If a released version has a bug, the fix is a new version, not an edit of the existing one.
- Dev Hub orgs cannot be sandboxes (with some exceptions). The Dev Hub is typically a production-class org.
- Managed package namespaces are permanent. Pick the namespace carefully because changing it requires creating a new package and migrating subscribers.
- Unlocked packages have weaker upgrade guarantees than managed packages. The subscriber org can edit unlocked package metadata, which can complicate later upgrades.
- First-generation packages and second-generation packages have different command surfaces. Mixing them is possible but requires careful tooling.
Trust & references
Cross-checked against the following references.
- Second-Generation Managed PackagingSalesforce Developer Docs
Straight from the source - Salesforce's reference material on Package Manager.
- Salesforce DX Developer GuideSalesforce Developer Docs
- Packaging GuideSalesforce Developer Docs
Hands-on resources to go deeper on Package Manager.
About the Author
Dipojjal Chakrabarti is a B2C Solution Architect with 29 Salesforce certifications and over 13 years in the Salesforce ecosystem. He runs salesforcedictionary.com to help admins, developers, architects, and cert/interview candidates sharpen their fundamentals. More about Dipojjal.
Test your knowledge
Q1. What is Package Manager in Salesforce DX?
Q2. What commands are part of Package Manager?
Q3. What does it replace?
Discussion
Loading discussion…