Building an extension follows the same packaging workflow as a standalone managed package, with the added step of declaring the base package as a dependency. The base package must be installed in the development org for the extension to compile against it.
- Install the base package in your development org
Get the base package install URL from the publisher or AppExchange. Install in your Partner Org or scratch org. The extension code needs to compile against the base; without it, references to base classes fail.
- Declare the dependency
For 2nd-Gen Managed and Unlocked: add the base package ID and minimum version to sfdx-project.json''s dependencies array. For 1st-Gen: configure in the packaging UI under Setup, Package, Dependencies.
- Build the extension components
Reference base package objects via lookups using the base namespace prefix (acme__Custom_Object__c). Call base global Apex methods using the namespace (acme.UtilityClass.doSomething()). Build new objects and components in your own extension namespace.
- Test against multiple base versions
Test the extension against the minimum supported base version and the latest base version. Major base version upgrades may require extension updates; test in advance.
- Package and distribute
Build the extension version via Salesforce CLI (sf package version create). Submit for AppExchange Security Review if distributing publicly. List on AppExchange with the base package called out as a requirement.
Minimum base version the extension requires. Match to the oldest base version your extension supports; allow newer.
AppExchange listing (most common for paid extensions) or direct install URL for internal or partner-specific distribution.
Extension uses its own namespace, separate from the base. Helps customer-side users distinguish base and extension metadata.
Per-seat licensing layered on top of the base package license. Customers typically pay both base and extension licenses.
- Install order matters. Base package first, then extension. Reversing the order fails with a Required Package Missing error.
- Uninstall order matters in reverse. Extension first, then base. Trying to uninstall the base while extensions reference it fails.
- Extension code can only call global Apex from the base package. Public and protected methods are not accessible across packages.
- Major base version upgrades may break extension compatibility. Test against new base versions before customers upgrade.
- Extension AppExchange listings must call out the base requirement prominently. Customers who miss the requirement install in the wrong order and blame the extension publisher.