Project Manifest
A Project Manifest is the package.xml file that lists the metadata components Salesforce moves into or out of an org. It is an XML document that names each component (or asks for all of a type with…
Definition
A Project Manifest is the package.xml file that lists the metadata components Salesforce moves into or out of an org. It is an XML document that names each component (or asks for all of a type with a wildcard) and sets the API version for the operation. Salesforce uses this manifest with the Metadata API deploy() and retrieve() calls, the Ant Migration Tool, the Salesforce CLI, and the VS Code extensions.
Think of it as the shopping list for a deployment. The manifest does not hold the metadata itself. It points to the components by type and name, and the tooling collects the matching source. People sometimes call sfdx-project.json the project manifest too, but that file is the DX project configuration, a separate thing covered below.
How package.xml drives every metadata move
Where the name "project manifest" comes from
Salesforce documentation uses the phrase project manifest in two related places, and both point at package.xml. The Metadata API guide describes the deploy() and retrieve() calls as exchanging a .zip file that contains a project manifest (package.xml) plus the component files organized into folders. The Ant Migration Tool guide has a page titled Constructing a Project Manifest, and that page is entirely about building package.xml. So when older docs, blog posts, or teammates say project manifest, they almost always mean this XML file. The confusion comes from Salesforce DX, where the file sfdx-project.json sits at the root of a project and gets loosely called the manifest as well. That second file is the project configuration, not a list of components. Keeping the two apart saves a lot of grief during deployments. The manifest in the package.xml sense is the one the Metadata API reads to decide what to retrieve or deploy. It is the file you hand to a command when you want a precise, repeatable set of components rather than everything in a folder.
The XML structure, element by element
A package.xml file has a single Package root and three kinds of content inside it. Each metadata grouping is a types element. Inside a types element you list one or more members entries, then exactly one name entry. The name holds the metadata type, such as ApexClass, CustomObject, or Flow. Each members entry holds the API name of a single component of that type, for example MyController for an ApexClass. To request every component of a type, use a members value of the asterisk wildcard instead of naming each one. At the bottom of the file, a single version element sets the API version, like 61.0, which tells Salesforce which release of the schema to apply. A small manifest might pull three Apex classes and one custom object. A large one can list hundreds of components across dozens of types. The order of types elements does not matter, but every component you name must exist in the source org for a retrieve, or in your local source for a deploy, or the tool reports it as missing.
Wildcards and their sharp edges
The asterisk wildcard is handy, but it does not behave the way many people expect, and the gaps cause real deployment bugs. When you wildcard CustomObject, Salesforce returns your custom objects but not standard objects, and not custom fields on standard objects. If you need a field on Account or Contact, you must name it explicitly and dot-qualify it, like Account.My_Field__c under the CustomField type. Several types that depend on an object definition cannot be wildcarded cleanly at all. The guide calls out CustomField, Picklist, RecordType, WebLink, and ValidationRule as components that you dot-qualify with the object name rather than grab with a bare asterisk. This is why a manifest built only from wildcards often misses the very metadata a release needs. Teams that rely on wildcards for a full backup are frequently surprised when standard-object customizations do not come along. The safe pattern is to wildcard the simple, standalone types and enumerate anything tied to an object. Tools that generate manifests from an org handle most of this for you, which is one reason hand-editing every entry is rarely worth it.
Generating a manifest instead of typing it
You rarely write package.xml by hand for anything large. The Salesforce CLI generates one for you with the project generate manifest command. Point it at an org with the from-org flag to capture what currently exists there, or build it from local files with the source-dir flag, or list specific types with the metadata flag. A common form is sf project generate manifest --from-org MyOrg --output-dir manifest, which writes package.xml into a manifest folder. Once you have the file, you feed it to the retrieve or deploy commands with the manifest flag, for example sf project retrieve start --manifest manifest/package.xml or sf project deploy start --manifest manifest/package.xml. The VS Code extensions add a Manifest Builder that lets you pick components from an org tree and produce the same file through a UI. DevOps Center can generate a manifest to seed a repository from an existing org. Whichever route you take, the output is the same package.xml, and any tool that speaks the Metadata API can consume it.
Deleting metadata with destructive manifests
A standard package.xml only adds or updates components. It never deletes. To remove metadata from an org, you pair package.xml with a companion file named destructiveChanges.xml that lists what to delete, using the same types, members, and name structure. The regular package.xml still ships alongside it, often holding just the version element when the deployment is delete-only. From API version 33.0 onward you can control timing by splitting deletes into destructiveChangesPre.xml and destructiveChangesPost.xml. The Pre file deletes components before the rest of the deployment runs, and the Post file deletes them after. This matters when an add and a delete in the same deployment depend on each other, for instance removing an old field only after a new one is in place. Destructive deployments are not tracked the way packaged metadata is, so review them carefully, because a wildcard in a destructive manifest can wipe far more than intended. Many teams generate these delta files automatically by comparing two commits, which keeps the manifest honest against what actually changed.
Manifest versus sfdx-project.json
Because both files anchor a project, it helps to state plainly what each one does. The package.xml manifest is transient and operation-specific. You create one for a given retrieve or deploy, and it answers a single question: which components am I moving right now. The sfdx-project.json file is durable project configuration. It declares the package directories where source lives, the sourceApiVersion used when converting and deploying, the namespace for managed work, the default login URL, and, for packaging, the package aliases, dependencies, and version numbers. The Salesforce CLI reads sfdx-project.json on nearly every command to understand the project layout, while it reads package.xml only when a command points to it. A healthy DX repository usually keeps both: a stable sfdx-project.json at the root, and one or more package.xml files under a manifest folder for ad hoc retrieves or for deployments that target a specific subset of metadata. Mixing the two roles, or expecting wildcards in one to behave like settings in the other, is a common source of failed pipelines.
How to build and use a package.xml manifest
You build a package.xml manifest either by generating it from an org with the Salesforce CLI or by editing the XML directly. The CLI route is faster and avoids most wildcard mistakes. Here is the generate-then-use flow.
- Open a DX project
Run the commands from the root of a Salesforce DX project, the folder that contains sfdx-project.json. The CLI needs that configuration present to know your package directories.
- Generate the manifest
Run sf project generate manifest --from-org YourOrgAlias --output-dir manifest to capture what exists in an authorized org, or use --source-dir force-app to build it from local source. The command writes package.xml into the manifest folder.
- Trim and set the API version
Open the generated package.xml, remove types you do not want, and confirm the version element matches the API version you intend to deploy against, for example 61.0.
- Use it in a command
Retrieve with sf project retrieve start --manifest manifest/package.xml, or deploy with sf project deploy start --manifest manifest/package.xml. Add --dry-run on a deploy to validate before committing changes.
One block per metadata grouping. Each block holds its members and a single name.
The API name of a component, or an asterisk to request every component of that type. Standard objects and their custom fields are not returned by a bare wildcard.
The metadata type for the block, such as ApexClass, CustomObject, or Flow. Exactly one per types block.
The API version for the operation, such as 61.0. One per file, at the Package root level.
- A wildcard on CustomObject skips standard objects and skips custom fields on standard objects. Name those explicitly.
- Types tied to an object (CustomField, RecordType, ValidationRule, WebLink, Picklist) must be dot-qualified, like Account.My_Field__c.
- package.xml never deletes anything. Use destructiveChanges.xml (or the Pre and Post variants from API 33.0) for removals.
- A retrieve fails if a named component does not exist in the source org, so generated manifests are safer than hand-typed ones.
Prefer this walkthrough as its own page? How to Project Manifest in Salesforce, step by step
Trust & references
Cross-checked against the following references.
Straight from the source - Salesforce's reference material on Project Manifest.
Hands-on resources to go deeper on Project Manifest.
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. Which file is the Project Manifest in a Salesforce DX project?
Q2. What does the Project Manifest declare for Second-Generation Packaging (2GP)?
Q3. Why does the Salesforce CLI read sfdx-project.json on every command?
Discussion
Loading discussion…