forcedotcom/sf-skills1 file

Dx Project Create

Scaffold a new Salesforce DX project of any template — standard, empty, analytics, agent, or a React/Angular UI-bundle app — and set it up end-to-end: relocate the session, connect an org, set the default, enable source tracking. Use when the user asks to create or scaffold a new Salesforce/SFDX project, start a new React/Angular Salesforce app, or run 'sf template generate project'. DO NOT TRIGGER for: building/editing/styling an EXISTING UI-bundle app (experience-ui-bundle-frontend-generate); scaffolding only a UI bundle as a step of building one out (experience-ui-bundle-project-generate, experience-ui-bundle-app-coordinate); tool validation (platform-environment-validate); org auth (login); project stats; scratch orgs (dx-org-manage).

Specification
Skill ID
forcedotcom/sf-skills/dx-project-create
Publisher
forcedotcom
Repository
sf-skills
Installs
0
Files
1
Synced
Sep 23, 2026
How to use it

Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.

forcedotcom/sf-skills/dx-project-createInstalls these files
  • SKILL.md

What this skill tells the agent

Creating a New Salesforce Project

Walk the user through a wizard that scaffolds a new Salesforce DX project, relocates this session into the new project, connects it to an org, and configures it for development. Run each step in order, confirming with the user before any environment-changing action.

The salesforce-development plugin's MCP servers (salesforce-api-context, salesforce-metadata-experts, salesforce-lsp) are provided by the installed plugin, not by the project — so they stay available in the new project automatically once the session relocates. There is no per-project .mcp.json to copy.

Step 1: Choose a Project Template

This skill scaffolds every template the CLI offers, including React/Angular UI-bundle apps — creating a project is a core capability and shouldn't require installing a separate plugin just to pick a template. (Once the project exists, the experience-ui-bundle-* skills own building it out — pages, components, styling, deploy — but the initial scaffold happens right here, whether or not that plugin is installed.)

Read the template set live from the CLI — never hardcode it, because Salesforce adds templates over time and a baked-in list goes stale:

sf template generate project --help

Parse the -t, --template=<option> line's <options: a|b|c|…> list — those pipe-separated names are the authoritative template set. As of writing the CLI offers eight, all scaffolded here: standard, empty, analytics, agent, plus the UI-bundle set reactinternalapp, reactexternalapp, angularinternalapp, angularexternalapp (React/Angular × internal/external audience). Treat the live parse as the source of truth; the list here is only a fallback if the parse fails.

Intent shortcut first. Take the shortcut only when the request fully resolves to exactly one template. Anything with a missing choice goes to the picker so it can ask — never guess. Resolve {template} directly when:

  • The request names a non-UI template: "empty/minimal project" → empty; "analytics project" → analytics; "agent project" → agent; "standard project" → standard.
  • The request is a UI-bundle app with BOTH framework AND audience clear → the matching UI template (e.g. "internal React app" → reactinternalapp, "customer-facing Angular portal" → angularexternalapp). Internal = employee-facing/already-authenticated; external = customer/partner-facing with a login flow.

A description of the app is NOT a template name. "Build me a personal todo app", "an inventory tracker", "a CRM for my team" describe what to build, not which template — they do NOT resolve to a template, so they do not qualify for the shortcut. Do not infer standard (or any template) from the app's purpose, however obvious it seems: standard being the picker's default does not license skipping the picker. When the user hasn't named a template or a framework, you must show the picker and let them choose — silently assuming a template is the exact miss this step exists to prevent.

Everything else falls through to the picker, including:

  • a bare "new project" / "create a Salesforce project" with no template named (the picker defaults to Standard),
  • a described app with no template or framework named ("a todo app", "an inventory tracker") — surface the picker; never assume the app's purpose maps to a template, and
  • a partially-specified UI app — e.g. "create a React app" with no audience. Never assume an audience. When the framework is already known but the audience isn't, skip the top-level picker and go straight to the framework/audience follow-up below to collect only the missing piece.

Otherwise ask one `AskUserQuestion` — "What kind of project?" (single-select, four options). AskUserQuestion caps at four choices, so the picker surfaces the four most-requested kinds; `empty` is deliberately picker-omitted and reached only via the intent shortcut above ("empty/minimal project"). That is intentional — empty is the rarely-picked bare-project template, and spending one of four scarce slots on it would crowd out a common choice. A user who wants it names it and the shortcut resolves it directly.

  • Standard → standard (the default) — general-purpose force-app metadata project (Apex, LWC, objects, flows).
  • Agentforce agent → agent — ships a sample Local Info Agent.
  • CRM Analytics → analytics (Tableau CRM) — adds the waveTemplates directory.
  • React / Angular UI app → a UI-bundle starter. This needs a framework + audience, so ask one follow-up `AskUserQuestion` ("Which UI framework and audience?", four options) that maps directly to {template}:
  • React — internal → reactinternalapp · React — external → reactexternalapp
  • Angular — internal → angularinternalapp · Angular — external → angularexternalapp
  • Internal = employee-facing/already-authenticated; external = customer/partner-facing with login, registration, and profile.

The resolved template is {template}, which feeds Step 3. If the live CLI adds a new template, add it here (or, if it's another rarely-picked one, wire it as an intent-shortcut keyword rather than a fifth picker slot).

Step 2: Choose a Project Name

Prompt the user for a project name. It becomes the new directory name and is interpolated into the shell commands below, so it MUST be strictly validated before any command uses it — never pass a raw name through.

Allowlist, then reject-and-re-prompt. Accept only names matching ^[A-Za-z0-9][A-Za-z0-9_-]*$ — letters, digits, _, and -, starting with a letter or digit. Anything else (spaces, path separators like /, a leading . or .., or shell metacharacters such as ; | & $ > < ( ) \ " ') is invalid: explain why and ask again. A name like proj;rm -rf ~ must never reach a command. As defense in depth, the commands below also quote "{name}"` — but validation is the real guard, not the quoting.

Step 3: Generate the Project

Verify before generating — do not run the command until you can check both:

  • ☐ The {name} about to be interpolated is the exact value that passed the Step 2 allowlist (^[A-Za-z0-9][A-Za-z0-9_-]*$) — not a raw, re-edited, or user-echoed string. If it never passed validation, go back to Step 2.
  • ☐ {template} is one of the CLI's advertised options from Step 1.
  • ☐ No {name}/ directory already exists in the current working directory — the generate would fail (or risk clobbering an existing project) if it does. Check with [ -e "{name}" ] first; if it exists, don't overwrite: tell the user and go back to Step 2 for a different name.

Run in the current working directory:

sf template generate project -t {template} -n "{name}"

This creates a new {name}/ directory under the current working directory. (sf project generate is the deprecated alias for this command — prefer template generate project.) No flatten step is needed — unlike a generate-into-an-existing-dir flow, this creates a fresh {name}/ whose sfdx-project.json is already at the root the session will relocate into.

UI-bundle templates carry npm dependencies — but do NOT install them for the user. A React/Angular starter isn't runnable (preview/build/lint fail) until its npm deps are present, and there are multiple package.json files — the project root and each UI bundle — each needing its own install. First-run install is the heavy step (multi-minute) and obvious through the latency, so it's a decision the developer should make explicitly — not something this skill runs unasked. Do not run npm install yourself. Instead, when {template} is a UI-bundle one (react*/angular*), tell the user in the closing message that deps aren't installed yet and hand them the commands to run when they're ready (see the UI-bundle pointer in the Closing Message).

More from forcedotcom

Use this skill in a project

Open any RiverX project, search the Skills panel for forcedotcom/sf-skills/dx-project-create, and install it in one click.

Use this skill