> For the complete documentation index, see [llms.txt](https://docs.flxbl.io/flxbl/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.flxbl.io/flxbl/sfp/concepts/supported-package-types/source-packages.md).

# Source Packages

A source package is a directory of metadata that sfp versions, builds into an [artifact](https://docs.flxbl.io/flxbl/sfp/concepts/artifacts), and deploys to an org through the Metadata API as a unit. It is the **default package type** in a flxbl project — see [Choosing a package type](https://docs.flxbl.io/flxbl/techniques/development-practices/choosing-a-package-type) for when to choose another.

Unlike an unlocked package, a source package has no Salesforce-side package version or component lock. sfp supplies the module's version, lifecycle, and deployment behaviour instead of the platform.

## When to use a source package

Source packages are the default, and they are the only option for some metadata:

* **Metadata the Metadata API supports but unlocked packaging does not** — see the [Metadata Coverage Report](https://developer.salesforce.com/docs/metadata-coverage).
* **Org-specific and environment-specific metadata** — queues, profiles, permission sets, custom settings, and components that vary across environments.
* **Configuration layered on managed packages** — help text, field descriptions, and similar changes to components a managed package delivers.
* **Metadata that needs destructive changes** — components removed through pre- and post-destructive entries.
* **Environment-specific variants of a component** — deploy a different variant per org with aliasified packages (a source-package-only capability, with an optional merge mode that shares common content), or swap configuration values at deploy with text replacements.

## What a source package provides

The properties that once required converting a source package to an unlocked package are provided by sfp and codev:

| Property                                   | Mechanism                                                                                                                                                                                                                                                                    |
| ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| A versioned, immutable artifact            | sfp builds the package into a versioned artifact, through the same build path as any other type.                                                                                                                                                                             |
| Deploys only the components that changed   | [Component checksum skip](https://docs.flxbl.io/flxbl/sfp/building-artifacts/configuring-installation-behaviour-of-a-package/component-checksum-skip) — on by default — fetches the previously installed artifact and deploys only the components whose source bytes differ. |
| Runs only the tests the change touches     | When checksum skip reduces the deploy, sfp sets the test level to `RunRelevantTests`.                                                                                                                                                                                        |
| Detecting when an org diverged from source | codev [environment drift detection](https://docs.flxbl.io/codev/environments/environment-drift) compares the source it expects on an environment against what the org contains.                                                                                              |
| Reconciling an org back to source          | [Sync](https://docs.flxbl.io/codev/ci-cd/sync) redeploys branch state to an environment; a [changeset](https://docs.flxbl.io/codev/ci-cd/overview-1) captures an org-side change and raises it as a pull request.                                                            |
| Removing components that left the module   | Pre- and post-destructive entries.                                                                                                                                                                                                                                           |

## Tradeoffs against unlocked packages

A source package does not carry a Salesforce-managed package version, so:

* **No platform component lock.** The org does not know package boundaries; another package can overwrite a component. Ownership rests on your repository structure, and divergence is caught by drift detection rather than prevented by the platform.
* **Dependencies are validated at deploy time**, against the target org, not when the package is built.

These are the reasons to choose an unlocked package for a given module — component ownership across orgs and build-time dependency validation. [Choosing a package type](https://docs.flxbl.io/flxbl/techniques/development-practices/choosing-a-package-type) covers the decision.

### Components commonly overwritten across packages

Without a platform lock, keep a single owner for components that several packages tend to touch:

* [Custom Labels](https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_customlabels.htm)
* Profiles and Permission Sets
* Custom Settings
* Global Value Sets

## Environment-specific configuration

Source packages support two mechanisms for environment-specific differences.

### Aliasified packages

Aliasified packages are a source-package-only capability: at install, sfp deploys the subfolder whose name matches the target org's alias, and falls back to a `default` subfolder when no alias matches.

```json
{
  "path": "src/src-env-specific",
  "package": "src-env-specific",
  "versionNumber": "2.0.10.NEXT",
  "aliasfy": true
}
```

```
src-env-specific/
├── default/          # fallback; deployed to sandboxes only
│   └── permissionsets/
├── dev/              # deployed to an org aliased "dev"
│   └── permissionsets/
└── prod/             # deployed to an org aliased "prod"
    └── permissionsets/
```

**Merge mode** adds content inheritance. With `"aliasfy": { "mergeMode": true }`, sfp merges the `default` folder's content into each alias subfolder at build time — an alias subfolder overrides only the files it redefines — so shared metadata is not duplicated across folders. In merge mode the `default` folder deploys to any environment, including production, and the package supports `push` and `pull` against the `default` subfolder.

```json
{
  "path": "src/src-env-specific",
  "package": "src-env-specific",
  "versionNumber": "2.0.10.NEXT",
  "aliasfy": { "mergeMode": true }
}
```

See [Aliasfy packages](/flxbl/sfp/building-artifacts/configuring-installation-behaviour-of-a-package/aliasfy-packages.md) and [merge mode](/flxbl/sfp/building-artifacts/configuring-installation-behaviour-of-a-package/aliasfy-packages/aliasfy-packages-merge-mode.md) for details.

### Text replacements

Replace configuration values during deployment without file duplication:

```yaml
# 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](/flxbl/sfp/building-artifacts/configuring-installation-behaviour-of-a-package/string-replacements.md) for details.

## Destructive changes

Source packages remove components 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 detected and processed during package installation.

## Apex test execution

* **Sandbox / scratch org**: tests are skipped by default for faster iteration.
* **Production**: tests always run and coverage is validated (a Salesforce requirement).
* **Overrides**:
  * `sfp install --runtests` forces test execution when installing to a sandbox.
  * Package-level `skipTesting` in `sfdx-project.json` (ignored in production, where every class deployed needs 75% coverage or more).

When [component checksum skip](https://docs.flxbl.io/flxbl/sfp/building-artifacts/configuring-installation-behaviour-of-a-package/component-checksum-skip) reduces the deploy, sfp narrows the test level to `RunRelevantTests`, so only the tests the deployed Apex touches run.

## Dependency management

A source package can depend on other source, unlocked, or managed packages. Dependencies are validated at deploy time — the dependent metadata must already exist in the target org.

For development in scratch orgs, declare dependencies so sfp installs them first:

```json
{
  "packageDirectories": [
    {
      "path": "src/my-package",
      "package": "my-package",
      "versionNumber": "1.0.0.NEXT",
      "dependencies": [
        {"package": "another-source-package"},
        {"package": "unlocked-package@1.2.3"},
        {"subscriberPackageVersionId": "04t..."}
      ]
    }
  ]
}
```

`sfp prepare` and `sfp validate` install declared dependencies before deploying the source package.

## Starting from unpackaged metadata

1. Identify logical groupings of metadata by domain.
2. Create source package entries in `sfdx-project.json`.
3. Move metadata into the package directories, keeping a single owner per component.
4. Declare dependencies between packages.
5. Deploy to a scratch org or sandbox to confirm order.

## Converting to an unlocked package

Converting is a deliberate choice for a specific module, not a step every package takes. Convert a module when you want platform-enforced component ownership or build-time dependency validation:

1. Confirm the module's components are stable.
2. Create the package in your DevHub and add its alias to `sfdx-project.json`.
3. Keep environment-specific and org-specific metadata as source packages.

The module boundary and its version history are unchanged; only how the module builds and deploys changes. See [Choosing a package type](https://docs.flxbl.io/flxbl/techniques/development-practices/choosing-a-package-type).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.flxbl.io/flxbl/sfp/concepts/supported-package-types/source-packages.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
