---
cuppy_hub: salesforce
cuppy_path: reference/dx/projects-and-source-format.md
cuppy_section: docs
cuppy_doc: 3BCQ-VCP5
cuppy_doc_uuid: 2c4f2590-9c62-4117-b8f7-2ba87d0c7b47
cuppy_permalink: https://cuppy.io/salesforce/d/3BCQ-VCP5
cuppy_version: 1
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/salesforce/docs/reference/dx/projects-and-source-format
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: f547989fc4c421a046a87e155cf13c8d6f12fd9432eeb97370ad34ca6d34047a
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---


# Salesforce DX projects

## The project file

`sf project generate --name demo --template standard` writes this `sfdx-project.json` (CLI 2.155.7):

```json
{
  "packageDirectories": [{ "path": "force-app", "default": true }],
  "name": "demo",
  "namespace": "",
  "sfdcLoginUrl": "https://login.salesforce.com",
  "sourceApiVersion": "67.0"
}
```

- `packageDirectories`: where source lives. More than one is allowed; Coral Cloud splits its app into `cc-base-app`, `cc-employee-app` and `cc-service-app`. Exactly one is `default`.
- `sourceApiVersion`: the metadata shape your files are written in. The CLI generated 67.0 even though Salesforce's docs list Winter '27 as 68.0: set it deliberately (`reference/orgs/orgs-and-editions.md`).
- `--template agent` creates an Agentforce DX starter project (`guides/agentforce/build-agent-with-agentforce-dx.md`). It includes an Agent Script authoring bundle, Apex and flow actions, a prompt template, permission sets and permission set groups, and a scratch definition.

## Source format vs metadata format

| | Source format (what you commit) | Metadata format (what the Metadata API deploys) |
|---|---|---|
| Layout | `force-app/main/default/<folder>/<Name>.<suffix>-meta.xml`, large types split up | One file per component plus `package.xml` |
| Example | `bots/Agent/Agent.bot-meta.xml` plus `bots/Agent/v1.botVersion-meta.xml` | `bots/Agent.bot` holding every version |
| Convert | `sf project convert source --source-dir force-app --output-dir mdapi-out` | `sf project convert mdapi --root-dir mdapi-out --output-dir force-app` |

The CLI maps folders and suffixes to types through Salesforce's metadata registry. Three strategies matter for agents:

| Strategy | Meaning | Examples |
|---|---|---|
| Plain | One `<Name>.<suffix>-meta.xml` file | `genAiPlugins/X.genAiPlugin-meta.xml`, `genAiPromptTemplates/X.genAiPromptTemplate-meta.xml`, `flows/X.flow-meta.xml` |
| **Decomposed** | One parent file plus child files in a folder | `Bot` → `bots/<Agent>/<Agent>.bot-meta.xml` + `v1.botVersion-meta.xml` |
| **Bundle** | A folder that deploys as one component | `aiAuthoringBundles/<Agent>/` (`<Agent>.agent` + `<Agent>.bundle-meta.xml`); `genAiFunctions/<Action>/` (meta file + `input/schema.json` + `output/schema.json`); `genAiPlannerBundles/<Agent>/` |
| Matching content | Code plus a meta file | `classes/X.cls` + `X.cls-meta.xml` |

The full list of Agentforce types: `reference/dx/agentforce-metadata-types.md`.

## Ignoring and listing

- `.forceignore` keeps files out of deploys and retrieves, with the same syntax as `.gitignore`. The generated one ignores `package.xml`, LWC config files, `**/__tests__/**` and `node_modules/`.
- `sf project generate manifest --source-dir force-app --name package` writes a `package.xml` from your source. `--from-org <alias>` lists everything in an org instead.

## Which API version a deploy uses

`sf project deploy start --api-version <v>` overrides the default, which per the CLI's help is "the latest version supported by the CLI". `sourceApiVersion` says which shape the files are in. The hub's reading: keep `sourceApiVersion` at or below the target org's maximum, and pass `--api-version` when an org is a release behind, as sandboxes are during preview windows.


---
<!-- cuppy -->
You are reading one file. The same content is free over MCP at https://cuppy.io/mcp with no signup: ranked search across all 376 documents in this hub, the merged view when you work in a layer, known workarounds matched to the error you hit, and depth control so you spend tokens on what you need. Start with the `_hello` tool. How to connect: https://cuppy.io/salesforce/ Something wrong in this document? Report it with the `session feedback` tool on the same endpoint.
<!-- /cuppy -->
