Skip to content
Development
Skill

/setup-local-sdk

Install a .NET SDK locally for safe preview testing, specific-version pinning, or reproducible team setups — without modifying the system-wide installation. USE FOR: trying .NET previews safely, testing specific SDK versions, installing MAUI or other workloads on a preview,

From plugin
skills
5.8k106 skills20 agents

Claude Code

$ npx -y skills add dotnet/skills --skill setup-local-sdk --agent claude-code

SKILL.md

setup-local-sdk.SKILL.md
name: setup-local-sdk
license: MIT
description: >
  Install a .NET SDK locally for safe preview testing, specific-version pinning, or
  reproducible team setups — without modifying the system-wide installation.
  USE FOR: trying .NET previews safely, testing specific SDK versions, installing MAUI
  or other workloads on a preview, updating or replacing an existing local SDK,
  creating reproducible team/CI install scripts, configuring global.json paths.
  DO NOT USE FOR: system-wide SDK installs, .NET hosts older than 10, runtime-only
  installs, or projects not using SDK-style commands.

setup-local-sdk

Purpose

Guide the user through installing a .NET SDK into a project-local `.dotnet/` directory and wiring it up via the `global.json` `paths` feature (.NET 10+). The examples use .NET 11, but this works with any version — prerelease or stable.

The result is a fully isolated SDK that:

  • Does **not** modify the system-wide .NET installation.
  • Is picked up automatically by `dotnet` commands from the project root.
  • Can be deleted to revert (`rm -rf .dotnet/` or `Remove-Item -Recurse -Force .\.dotnet`).

When NOT to use

  • User wants a **system-wide** install — direct to the official installer.
  • Host `dotnet` is **older than v10** — `paths` doesn't exist; explain and stop.
  • User needs a **runtime-only** install — `paths` applies to SDK resolution only.

Inputs / Prerequisites

| Input | Required | Default | Notes | |---|---|---|---| | Channel or version | No | `11.0` | e.g. `11.0`, `STS`, `LTS`, or an exact version like `11.0.100-preview.2.26159.112` | | Quality | No | `preview` | One of: `daily`, `preview`, `ga` | | jq | No | — | Optional for bash team scripts when patching an existing `global.json`; without it, do not overwrite the file |

Prerequisites

1. **A .NET 10+ SDK is installed globally** — run `dotnet --version`; major ≥ 10. 2. **curl** (macOS/Linux) or **PowerShell** (Windows) is available.

Workflow

Step 1 — Clarify what to install

If the user didn't specify, ask what .NET SDK version they want (e.g., "latest .NET 11 preview" or an exact version like `11.0.100-preview.2.26159.112`). Map the answer to `--channel`/`--quality` or `--version` flags.

Step 2 — Verify .NET 10+ host

If the user already provided `dotnet --version` output, treat that as the authoritative version for their machine. Do not override it with the agent workspace's version; if the two differ, explain that the workspace differs and continue advising for the user's machine.

dotnet --version

If major version < 10, stop before downloading anything: the `paths` feature requires a .NET 10+ host SDK. Tell the user to install .NET 10 or later system-wide first, then return to the local SDK setup.

Step 3 — Detect operating system

Run `uname -s 2>/dev/null`. If it succeeds (including `MINGW*`, `MSYS*`, `CYGWIN*` — these are bash-capable environments like Git Bash) → use bash/`dotnet-install.sh`. If it fails (native Windows without Git Bash) → use PowerShell/`dotnet-install.ps1`.

Step 4 — Check for existing local SDK

**macOS / Linux:**

test -d .dotnet && echo "exists" || echo "not found"

**Windows (PowerShell):**

if (Test-Path -LiteralPath .\.dotnet) { "exists" } else { "not found" }

If `.dotnet/` exists, ask: update with the new version, or skip and keep it?

Step 5 — Download and run the install script

**macOS / Linux:**

INSTALL_SCRIPT="$(mktemp "${TMPDIR:-/tmp}/dotnet-install.XXXXXX")"
trap 'rm -f "$INSTALL_SCRIPT"' EXIT
curl -fsSL https://dot.net/v1/dotnet-install.sh -o "$INSTALL_SCRIPT"
bash "$INSTALL_SCRIPT" --channel <CHANNEL> --quality <QUALITY> --install-dir .dotnet

**Windows (PowerShell):**

$installScript = Join-Path $env:TEMP "dotnet-install-$([guid]::NewGuid()).ps1"
try {
    Invoke-WebRequest -Uri 'https://dot.net/v1/dotnet-install.ps1' -OutFile $installScript
    & $installScript -Channel <CHANNEL> -Quality <QUALITY> -InstallDir .dotnet
}
finally {
    if (Test-Path -LiteralPath $installScript) {
        Remove-Item -LiteralPath $installScript -Force
    }
}

For exact versions: use `--version <VERSION>` (bash) or `-Version <VERSION>` (PowerShell) instead of channel/quality flags. The install scripts are from Microsoft's official URLs: `https://dot.net/v1/dotnet-install.sh` and `https://dot.net/v1/dotnet-install.ps1`.

Step 6 — Identify the installed version

./.dotnet/dotnet --version          # macOS/Linux
.\.dotnet\dotnet.exe --version      # Windows

Record the exact version string (e.g., `11.0.100-preview.2.26159.112`) for `global.json`.

Step 7 — Create or update global.json

{
  "sdk": {
    "version": "<INSTALLED_VERSION>",
    "allowPrerelease": true,
    "rollForward": "latestFeature",
    "paths": [".dotnet", "$host$"],
    "errorMessage": "Required .NET SDK not found. Run ./install-dotnet.sh (or .ps1) to install it locally."
  }
}
  • `paths`: `.dotnet` first (local priority), `$host$` = system-wide fallback.
  • `rollForward: "latestFeature"`: use for latest-preview or floating feature-band installs.
  • Exact version requests: use `rollForward: "disable"` so SDK resolution doesn't move to a different feature band.
  • `allowPrerelease`: set to `true` only when installing a prerelease SDK. Omit for stable versions.
  • `errorMessage`: include only when team install scripts are created (Step 10). Otherwise omit.

If `global.json` already exists, **merge** carefully: preserve existing properties (`msbuild-sdks`, `tools`, etc.) and only add/update the `sdk` section. Read the existing file first, update/add the `sdk` object, then write it back. This ensures cross-project config (e.g., MSBuild settings) isn't lost. Always back up the original file (e.g., `global.json.bak`) before modifying.

**Minimal config** (when version pinning isn't needed): `{"sdk":{"paths":[".dotnet","$host$"]}}`

Step 8 — Update .gitignore

**macOS / Linux (o

Read more
@dotnet
Ships withskills

This repository contains the .NET team's curated set of portable skills and host-specific custom agents for coding agents. For information about the Agent Skills standard, see agentskills.io.

5.8k106 skills20 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
5.8k
Star history of dotnet/skills on GitHub, a chart by star-history.com

Other skills on skills.

csharp-scripts

csharp-scripts

Run file-based C# apps with the .NET CLI when the user explicitly wants C#/.NET code without creating a project. Use for C#…

@dotnet@dotnetInstall Skill
dotnet-pinvoke

dotnet-pinvoke

Correctly call native (C/C++) libraries from .NET using P/Invoke and LibraryImport. Covers function signatures, string…

@dotnet@dotnetInstall Skill
nuget-trusted-publishing

nuget-trusted-publishi…

Set up NuGet trusted publishing (OIDC) on a GitHub Actions repo — replaces long-lived API keys with short-lived tokens. USE FOR:…

@dotnet@dotnetInstall Skill
vectorization

vectorization

Design, implement, optimize, and review SIMD code in .NET. USE FOR: vectorizing scalar loops with TensorPrimitives,…

@dotnet@dotnetInstall Skill
technology-selection

technology-selection

Guides technology selection and implementation of AI and ML features in .NET 8+ applications using ML.NET,…

@dotnet@dotnetInstall Skill

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills2w309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc2w293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react5d252k
@facebook@facebookInstall Skill

Questions about setup-local-sdk.

Which coding agents can use setup-local-sdk?
setup-local-sdk installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.