Source Packages
Availability
✅
✅
Source Packages is an sfp feature that provides a flexible alternative to native unlocked packages for metadata deployment and organization.
Understanding Source Packages
Source Packages are metadata deployments from a Salesforce perspective - they are groups of components that are deployed to an org as a unit. Unlike Unlocked packages which are First Class Salesforce deployment constructs with lifecycle governance (versioning, component locking, automated dependency validation), source packages provide more flexibility at the cost of some safety guarantees.
When to Use Source Packages
While we generally recommend using unlocked packages over source packages for production code, source packages excel in several scenarios:
Ideal Use Cases
Application Configuration: Configuring applications delivered by managed packages (e.g., changes to help text, field descriptions)
Org-Specific Metadata: Global or org-specific components (queues, profiles, permission sets, custom settings)
Environment-Specific Configuration: Components that vary significantly across environments
Composite UI Layouts: Complex UI configurations that don't package well
Rapid Development: When iteration speed is more important than package versioning
Large Monolithic Applications: When breaking into unlocked packages is not feasible
Starting Package Development: Teams beginning their journey to package-based development
Technical Constraints Favoring Source Packages
Known bugs or limitations with unlocked package deployment
Unlocked Package validation taking too long (consider org-dependent as alternative)
Need for destructive changes support
Requirement for environment-specific text replacements
Source Packages vs Unlocked Packages
Advantages of Source Packages
Deployment Speed: Significantly faster deployment times (no package creation/validation overhead)
Testing Control: Flexible test execution - can skip tests in sandboxes for faster iterations (see Testing Behavior)
Environment Management: Support for aliasified folders and text replacements for environment-specific configurations
Destructive Changes: Full support for pre and post-destructive changes
Metadata Coverage: Supports all metadata types, including those not supported by unlocked packages
No Version Constraints: No need to manage package versions or dependencies at the platform level
Quick Fixes: Can deploy hotfixes immediately without package creation
Development Flexibility: Easier to refactor and reorganize code
Disadvantages of Source Packages
No Component Locking: Salesforce org is unaware of package boundaries - components can be overwritten by other packages
No Platform Validation: Dependencies are not validated by Salesforce
No Automated Rollback: Cannot easily rollback to previous versions
Manual Destructive Changes: Must be explicitly managed through pre/post-destructive folders
No Package Lifecycle: No built-in versioning, upgrade, or deprecation paths
Dependency Risks: Dependencies only validated at deployment time
Production Risk: Higher risk of deployment failures in production
Common Override Scenarios
Metadata components that commonly get overridden across packages:
Profiles and Permission Sets
Custom Settings
Global Value Sets
Advanced Features (sfp-pro)
Environment-Specific Configuration
Source packages in sfp-pro support two powerful mechanisms for managing environment-specific differences:
1. Aliasified Packages
Deploy different metadata variants based on org aliases:
src-env-specific/
└── main/
├── default/ # Fallback for sandboxes
│ └── classes/
├── dev/ # Dev-specific metadata
│ └── classes/
└── prod/ # Production metadata
└── classes/
See Aliasified Packages for details.
2. Text Replacements
Replace configuration values during deployment without file duplication:
# preDeploy/replacements.yml
replacements:
- name: "API Endpoint"
glob: "**/*.cls"
pattern: "%%API_URL%%"
environments:
default: "https://api.dev.example.com"
prod: "https://api.example.com"
See String Replacements for details.
Destructive Changes Support
Source packages fully support destructive changes through dedicated folders:
pre-destructive/: Components deleted before deployment
post-destructive/: Components deleted after deployment
my-package/
├── main/
│ └── default/
├── pre-destructive/ # Deleted before main deployment
│ └── objects/
└── post-destructive/ # Deleted after main deployment
└── classes/
Destructive changes are automatically detected and processed during package installation.
Testing Behavior
Source packages have intelligent test execution control:
Development/Sandbox: Tests skipped by default for faster iterations
Production: Tests always run (Salesforce requirement)
Override Options:
sfp install --runtests
: Force test executionPackage-level
skipTesting
in sfdx-project.json
This provides significant performance improvements during development while maintaining production safety.
Dependency Management
Source packages can depend on other unlocked packages or managed packages. Dependencies are validated at deployment time, meaning the dependent metadata must already exist in the target org.
For development in scratch orgs, you can add dependencies to enable automatic installation:
{
"packageDirectories": [
{
"path": "src/my-package",
"package": "my-package",
"versionNumber": "1.0.0.NEXT",
"dependencies": [
{"package": "another-source-package"},
{"package": "[email protected]"},
{"subscriberPackageVersionId": "04t..."}
]
}
]
}
sfp commands like prepare
and validate
will automatically install dependencies before deploying the source package.
Best Practices
Use unlocked packages for shared libraries that need version control and component protection
Use source packages for environment-specific configuration and org-specific metadata
Organize large source packages into logical domains for better maintainability
Leverage aliasified packages for structural differences between environments
Use text replacements for configuration values that change across environments
Document destructive changes clearly in your release notes
Test in lower environments before production deployment
Consider org-dependent unlocked packages as a middle ground when validation time is a concern
Migration Paths
From Unpackaged Metadata
Identify logical groupings of metadata
Create source package entries in sfdx-project.json
Move metadata into package directories
Define dependencies between packages
Test deployment order
To Unlocked Packages
Start with source packages to organize metadata
Identify stable components suitable for packaging
Gradually convert source packages to unlocked packages
Keep environment-specific components as source packages
Last updated