migration-from-change-sets-to-sfdx

Use when planning or executing a migration from change-set-based deployments to Salesforce DX source-driven development. Trigger keywords: 'migrate from change sets', 'move to SFDX', 'convert metadata to source format', 'sf project convert mdapi', 'source-driven development adoption'. NOT for greenfield SFDX project setup (use sf-cli-and-sfdx-essentials), unlocked package design (use unlocked-package-development), or DevOps Center pipeline creation (use devops-center-pipeline).

Best use case

migration-from-change-sets-to-sfdx is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Use when planning or executing a migration from change-set-based deployments to Salesforce DX source-driven development. Trigger keywords: 'migrate from change sets', 'move to SFDX', 'convert metadata to source format', 'sf project convert mdapi', 'source-driven development adoption'. NOT for greenfield SFDX project setup (use sf-cli-and-sfdx-essentials), unlocked package design (use unlocked-package-development), or DevOps Center pipeline creation (use devops-center-pipeline).

Teams using migration-from-change-sets-to-sfdx should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/migration-from-change-sets-to-sfdx/SKILL.md --create-dirs "https://raw.githubusercontent.com/PranavNagrecha/AwesomeSalesforceSkills/main/skills/devops/migration-from-change-sets-to-sfdx/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/migration-from-change-sets-to-sfdx/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How migration-from-change-sets-to-sfdx Compares

Feature / Agentmigration-from-change-sets-to-sfdxStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Use when planning or executing a migration from change-set-based deployments to Salesforce DX source-driven development. Trigger keywords: 'migrate from change sets', 'move to SFDX', 'convert metadata to source format', 'sf project convert mdapi', 'source-driven development adoption'. NOT for greenfield SFDX project setup (use sf-cli-and-sfdx-essentials), unlocked package design (use unlocked-package-development), or DevOps Center pipeline creation (use devops-center-pipeline).

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Migration From Change Sets To SFDX

This skill activates when a team or practitioner needs to transition from the point-and-click change set deployment model to Salesforce DX source-driven development. It covers the canonical migration path: retrieving metadata from an org via the Metadata API, converting it to source format with `sf project convert mdapi`, establishing a git-tracked SFDX project, and adopting CLI-based deployment workflows. The skill guides incremental, component-by-component migration to preserve git history and minimize disruption to in-flight releases.

---

## Before Starting

Gather this context before working on anything in this domain:

- Which metadata types are currently deployed via change sets? Get a rough inventory: Apex classes, triggers, Flows, custom objects, page layouts, permission sets, reports.
- Has the team authenticated any orgs with `sf org login`? Is a Dev Hub enabled if packages are the eventual target?
- Does a git repository already exist for this org's metadata, or is this a from-scratch setup?
- What is the team's Salesforce edition? Source tracking is only available in scratch orgs and Developer/Developer Pro sandboxes. Full-copy and partial-copy sandboxes require manifest-based retrieval.
- Are there active change set deployments in flight that must complete before the migration cutover?

---

## Core Concepts

### Metadata API Format vs. Source Format

Salesforce metadata exists in two on-disk representations. **Metadata API format** (also called "mdapi format") is the legacy structure produced by `sf project retrieve start --metadata-dir` or the older `sfdx force:mdapi:retrieve`. Files land in a flat directory with `package.xml` at the root and subdirectories like `classes/`, `objects/`, `flows/`. **Source format** is the decomposed structure used by SFDX projects: a single custom object is split into individual files per field, per list view, per validation rule under `force-app/main/default/objects/ObjectName/`. Source format is designed for version control — smaller files, cleaner diffs, fewer merge conflicts.

The conversion command `sf project convert mdapi --root-dir <mdapi-dir> --output-dir <source-dir>` transforms metadata API format into source format. This is a one-way formatting conversion; it does not deploy or retrieve anything.

### Incremental Component Migration

The recommended approach is not a one-time "big bang" conversion of the entire org. Instead, migrate component groups incrementally — starting with the most actively changed metadata types (Apex classes, LWC, Flows) and leaving stable, rarely-changed metadata (reports, dashboards, email templates) for later phases. Each batch is retrieved, converted, committed to git, and validated with a round-trip deploy to a sandbox. This preserves meaningful git history (each commit represents a logical component group) and limits blast radius if something goes wrong.

### package.xml as the Migration Manifest

During migration, `package.xml` serves as the manifest that controls what gets retrieved from the source org. You can retrieve everything at once with wildcard members (`<members>*</members>`), but this pulls hundreds of standard and managed-package components you do not own. Best practice is to build a targeted `package.xml` listing only the metadata types and specific members your team maintains. This manifest becomes the basis for your ongoing manifest-based deploy workflow if you do not adopt packages.

### Source Tracking vs. Manifest-Based Workflow

After migration, the team must choose a deployment model. **Source tracking** (`sf project deploy start` / `sf project retrieve start` with no manifest) works in scratch orgs and select sandbox types — it automatically tracks local and remote changes. **Manifest-based deployment** (`sf project deploy start --manifest package.xml`) works in any org and is the direct replacement for change sets. **Unlocked packages** group metadata into versioned, installable units. Most teams migrating from change sets start with manifest-based deploys and graduate to packages once the project structure is stable.

---

## Common Patterns

### Pattern 1: Phased Retrieval and Conversion

**When to use:** The org has 200+ components deployed via change sets and the team wants a controlled migration over 2-4 sprints.

**How it works:**

1. Build a `package.xml` listing one metadata type group at a time (e.g., all Apex classes first).
2. Retrieve: `sf project retrieve start --manifest package.xml --target-org prod --output-dir mdapi-output/`
3. Convert: `sf project convert mdapi --root-dir mdapi-output/ --output-dir force-app/`
4. Review the converted source, commit to git with a descriptive message ("Add Apex classes from production").
5. Validate with a round-trip deploy to a sandbox: `sf project deploy start --source-dir force-app/ --target-org dev-sandbox`
6. Repeat for the next metadata type group (custom objects, flows, LWC, etc.).

**Why not big bang:** A single retrieve-and-convert of everything produces one massive commit with no logical grouping, makes merge conflicts likely if anyone else is working, and if conversion fails on one type the entire batch must be redone.

### Pattern 2: Shadow Period (Parallel Change Set + CLI Deploys)

**When to use:** The team cannot stop releasing during migration. Some team members are still learning the CLI.

**How it works:**

1. Convert existing metadata to source format and commit to git (using Pattern 1).
2. For the next 1-2 release cycles, deploy to production using both the old change set process and the new CLI process simultaneously. The CLI deploy is validate-only (`--dry-run`) to confirm parity.
3. Once 2-3 consecutive releases pass CLI validation without issues, cut over fully to CLI deploys.
4. Retire the change set workflow and update runbooks.

**Why not immediate cutover:** Teams unfamiliar with the CLI will make mistakes under release pressure. A shadow period builds confidence without risking production stability.

### Pattern 3: Direct-to-Packages Migration

**When to use:** The org has clear domain boundaries (Sales objects, Service objects, Integration logic) and the team plans to adopt unlocked packages.

**How it works:**

1. Retrieve and convert metadata following Pattern 1.
2. Organize source into multiple `packageDirectories` in `sfdx-project.json`, one per domain.
3. Create unlocked packages for each directory using `sf package create`.
4. Create package versions and install in a sandbox for validation.
5. Deploy packages to production instead of using manifest-based deploys.

**Why not start here:** This adds packaging complexity on top of the format migration. Only suitable for teams with a clear modular architecture and Dev Hub access.

---

## Decision Guidance

| Situation | Recommended Approach | Reason |
|---|---|---|
| Small team (1-3 admins), simple org, infrequent releases | Pattern 1 + manifest-based deploys | Low overhead, minimal tooling setup, direct change-set replacement |
| Mid-size team, regular release cadence, cannot pause releases | Pattern 2 (shadow period) | Builds team confidence while maintaining release continuity |
| Large team, modular org architecture, Dev Hub available | Pattern 3 (direct to packages) | Packages provide versioning, dependency management, and installation governance |
| Org has heavy managed-package customizations | Pattern 1, exclude managed-package components from package.xml | Managed-package metadata cannot be deployed via CLI; only your customizations migrate |
| Team uses DevOps Center already | Skip CLI manifest deploys; convert source format and connect to DevOps Center | DevOps Center handles deployment orchestration; you just need the source format conversion |

---

## Recommended Workflow

Step-by-step instructions for an AI agent or practitioner executing this migration:

1. **Inventory current state** — List all metadata types currently promoted via change sets. Check recent change set history in Setup > Outbound Change Sets. Identify which components change frequently vs. rarely.
2. **Set up the SFDX project** — Run `sf project generate --name <project-name>`. Initialize a git repository if none exists. Authenticate the source org with `sf org login web --alias prod`.
3. **Build the migration manifest** — Create a `package.xml` targeting the first batch of metadata types. Start with Apex classes and triggers (they have the clearest file-to-component mapping).
4. **Retrieve and convert** — Run `sf project retrieve start --manifest package.xml --target-org prod --output-dir mdapi-output/`. Then `sf project convert mdapi --root-dir mdapi-output/ --output-dir force-app/`. Review the output structure.
5. **Validate round-trip** — Deploy the converted source to a sandbox: `sf project deploy start --source-dir force-app/ --target-org dev-sandbox`. Confirm zero errors. This proves the conversion is lossless.
6. **Commit and iterate** — Commit the converted source to git. Repeat steps 3-5 for each remaining metadata type group. Resolve conflicts between batches as they arise.
7. **Cut over** — Once all actively-maintained metadata is in the SFDX project, perform the next production release via `sf project deploy start` instead of a change set. Retire the change set process.

---

## Review Checklist

Run through these before marking the migration complete:

- [ ] All actively-maintained metadata types are retrieved and converted to source format
- [ ] Source format files are committed to a git repository with logical, per-batch commits
- [ ] Round-trip deploy to a sandbox succeeds with zero errors for the full source directory
- [ ] `sfdx-project.json` has correct `sourceApiVersion` matching the org's current API version
- [ ] `.forceignore` is configured to exclude metadata the team does not own (managed-package components, standard objects not customized)
- [ ] Team members have authenticated their orgs with `sf org login` and can run basic CLI commands
- [ ] At least one production deploy has been completed via CLI (validate-only counts for the shadow period)
- [ ] Change set workflow is formally retired and runbooks are updated

---

## Salesforce-Specific Gotchas

Non-obvious platform behaviors that cause real production problems:

1. **`sf project convert mdapi` silently skips unsupported types** — Some metadata types (e.g., InstalledPackage, certain legacy email template types) are not supported in source format. The convert command does not error; it just omits them. Always compare the count of components in the mdapi directory against the converted source directory to catch dropped items.

2. **Source API version mismatch breaks retrieval** — If `sfdx-project.json` specifies `"sourceApiVersion": "59.0"` but the org is on API version 62.0, certain newer metadata types will not be retrieved or may have missing fields. Always set `sourceApiVersion` to match the target org's current release API version.

3. **Object decomposition creates hundreds of files** — Converting a single custom object with 80 fields, 10 validation rules, and 5 list views from mdapi format produces 95+ individual files in source format. This is by design, but teams unfamiliar with source format are alarmed by the file count. Prepare the team for this before the first conversion.

4. **Profiles and permission sets do not round-trip cleanly** — Retrieved profiles contain every object and field permission in the org, including standard objects and managed-package fields. Deploying this back overwrites the target org's profile with exactly what was retrieved, potentially removing permissions granted after retrieval. Use `.forceignore` to exclude profiles, or use permission sets exclusively.

5. **Flows retrieved in mdapi format include inactive versions** — A retrieve with `<members>*</members>` for FlowDefinition pulls all versions, including inactive ones. Converting these creates source files for flows the team may not recognize. Use specific member names in `package.xml` to retrieve only the active flow versions you intend to manage.

---

## Output Artifacts

| Artifact | Description |
|---|---|
| Migration plan | Phased schedule mapping metadata type groups to sprint iterations, with owners and validation milestones |
| SFDX project | Initialized project with `sfdx-project.json`, `.forceignore`, and `force-app/` containing converted source |
| package.xml manifest | Targeted retrieval manifest listing only team-maintained metadata types and members |
| Validation report | Results of round-trip deploy to sandbox confirming conversion fidelity |
| Cutover checklist | Go/no-go criteria for switching the next production release from change sets to CLI deploys |

---

## Related Skills

- `devops/change-set-deployment` — Use when the team is still using change sets and needs help with the current workflow, not the migration away from it.
- `apex/sf-cli-and-sfdx-essentials` — Use when the question is about SF CLI commands, authentication, or scratch org basics rather than the migration process itself.
- `devops/unlocked-package-development` — Use when the team has completed the source-format migration and is ready to adopt unlocked packages.
- `devops/scratch-org-management` — Use when setting up scratch orgs as part of the post-migration development workflow.
- `apex/metadata-api-and-package-xml` — Use when the question is about package.xml authoring, metadata type references, or retrieval patterns rather than the migration workflow.

Related Skills

vlocity-to-native-omnistudio-migration

8
from PranavNagrecha/AwesomeSalesforceSkills

Use when migrating an org from the Vlocity managed package (vlocity_ins, vlocity_cmt, vlocity_ps) to native OmniStudio. Trigger keywords: Vlocity to OmniStudio migration, namespace migration, vlocity_ins to omnistudio, OmniStudio Migration Tool, DataRaptor namespace update, OmniScript JSON export, managed package to native. NOT for new OmniStudio setup in greenfield orgs, nor for migrating between OmniStudio-native orgs, nor for Salesforce CPQ to Industries CPQ migration.

omnistudio-lwc-omniscript-migration

8
from PranavNagrecha/AwesomeSalesforceSkills

Migrate classic Visualforce-based OmniScripts to LWC-based runtime with feature parity and regression testing. NOT for new OmniScript design.

visualforce-to-lwc-migration

8
from PranavNagrecha/AwesomeSalesforceSkills

Migrating Visualforce pages and components to Lightning Web Components: controller-to-Apex-method translation, viewstate replacement, custom URL parameter handling, PageReference-to-NavigationMixin mapping, Lightning Out coexistence, and inline VF retention strategy. NOT for new LWC development from scratch (use lwc-fundamentals) or Aura-to-LWC migration (use aura-to-lwc-migration).

lwc-locker-to-lws-migration

8
from PranavNagrecha/AwesomeSalesforceSkills

Migrating LWCs from Lightning Locker Service to Lightning Web Security (LWS) — flipping the org switch safely, identifying components likely to break, removing Locker workarounds that are now insecure, and validating third-party libraries that previously failed under SecureWindow/SecureElement proxies. NOT for Aura → LWC migration — see lwc/aura-to-lwc-migration. NOT for general LWC security review (XSS, public-API hardening) — see lwc/lwc-security and lwc/lwc-public-api-hardening.

aura-to-lwc-migration

8
from PranavNagrecha/AwesomeSalesforceSkills

Migrating Aura components to LWC: feature mapping, interoperability wrappers, event translation, navigation patterns, and Aura-LWC coexistence strategies. NOT for new LWC development from scratch or Aura feature development.

change-data-capture-integration

8
from PranavNagrecha/AwesomeSalesforceSkills

Use this skill when setting up CDC to stream Salesforce record changes to external systems via CometD or Pub/Sub API. Covers change event channels, entity selection, event structure, replay ID management, gap events, and subscriber management. NOT for Apex CDC trigger subscribers (see apex/platform-events-apex). NOT for publishing custom business events (use integration/platform-events-integration).

workflow-rule-to-flow-migration

8
from PranavNagrecha/AwesomeSalesforceSkills

Migrate Workflow Rules to record-triggered Flows: field update mapping, email alert migration, outbound message alternatives using Flow Core Actions, time-based workflow replacement with Scheduled Paths. NOT for Process Builder migration (use process-builder-to-flow-migration), NOT for building new flows from scratch.

process-builder-to-flow-migration

8
from PranavNagrecha/AwesomeSalesforceSkills

Migrate Process Builder processes to record-triggered Flows using the native Migrate to Flow tool or manual rebuild. Covers conversion tool usage, pattern mapping, order-of-execution changes, testing migrated flows, and bulk behavior improvements. NOT for building new flows from scratch, NOT for Workflow Rule migration (use workflow-rule-to-flow-migration), NOT for net-new automation design.

flow-migration-from-trigger

8
from PranavNagrecha/AwesomeSalesforceSkills

Decide whether an existing Apex trigger should be rewritten as a Flow, and execute the migration safely. Covers the decision criteria (complexity, ownership, performance), side-by-side rollout, test-coverage parity, and the inverse case (recognize when Flow should stay Apex). NOT for migrating Process Builder / Workflow Rule to Flow (use those migration skills). NOT for brand-new automation decisions (use automation-selection.md).

sfdx-monorepo-patterns

8
from PranavNagrecha/AwesomeSalesforceSkills

Structure a single repo with multiple unlocked packages, shared templates, and cross-package test strategies. NOT for multi-repo org strategies.

sfdx-hardis-integration

8
from PranavNagrecha/AwesomeSalesforceSkills

Adopt sfdx-hardis for org monitoring, CI pipelines, and release automation. NOT for writing plugins to sfdx-hardis itself.

destructive-changes-deployment

8
from PranavNagrecha/AwesomeSalesforceSkills

Managing destructiveChanges.xml manifests for safe metadata deletion in Salesforce deployments. Use when deleting metadata components via Metadata API or sf CLI. Covers pre vs post destructive manifests, safe deletion sequencing, dependency handling. NOT for package.xml basics (use metadata-api-and-package-xml). NOT for basic deployment setup (use change-set-deployment).