Installs and manages .NET tools. Global, local, manifests, restore, version pinning.
Consumer-side management of .NET CLI tools: installing global and local tools, creating and maintaining
.config/dotnet-tools.json manifests, version pinning for team reproducibility, dotnet tool restore in CI pipelines,
updating and uninstalling tools, and troubleshooting common tool issues.
Version assumptions: .NET 8.0+ baseline. Local tools and tool manifests available since .NET Core 3.0. RID-specific tool packaging available since .NET 10.
Cross-references: [skill:dotnet-cli-packaging] for tool authoring and NuGet packaging, [skill:dotnet-cli-distribution] for distribution strategy and RID matrix, [skill:dotnet-cli-release-pipeline] for automated release workflows, [skill:dotnet-project-analysis] for detecting existing tool manifests.
Global tools are installed per-user and available from any directory. The tool binaries are added to a directory on the user's PATH.
# Install a global tool
dotnet tool install -g <package-id>
# Install a specific version
dotnet tool install -g <package-id> --version 1.2.3
# Install a pre-release version
dotnet tool install -g <package-id> --version "*-rc*"
# List installed global tools
dotnet tool list -g
# Update a global tool to the latest stable version
dotnet tool update -g <package-id>
# Uninstall a global tool
dotnet tool uninstall -g <package-id>
```text
**Default install locations:**
| OS | Path |
|-----|------|
| Linux/macOS | `$HOME/.dotnet/tools` |
| Windows | `%USERPROFILE%\.dotnet\tools` |
Global tools are user-scoped, not machine-wide. Each user maintains their own tool installations independently.
### Custom Install Location
Use `--tool-path` to install to a custom directory. The directory is not automatically added to PATH -- you must manage PATH yourself:
```bash
dotnet tool install <package-id> --tool-path ~/my-tools
```bash
---
## Local Tool Installation
Local tools are scoped to a directory tree and tracked in a manifest file. Different directories can use different versions of the same tool.
### Creating the Tool Manifest
The manifest file `.config/dotnet-tools.json` tracks local tool versions. Create it at the repository root:
```bash
# Create the manifest (first time only, at repo root)
dotnet new tool-manifest
```bash
This produces:
```json
{
"version": 1,
"isRoot": true,
"tools": {}
}
```text
Commit this file to source control so all team members share the same tool versions.
### Installing Local Tools
Omit the `-g` flag to install a tool locally. The tool is recorded in the nearest manifest file:
```bash
# Install a local tool (recorded in .config/dotnet-tools.json)
dotnet tool install <package-id>
# Install a specific version
dotnet tool install <package-id> --version 2.0.1
# List local tools
dotnet tool list
# Update a local tool
dotnet tool update <package-id>
# Uninstall a local tool
dotnet tool uninstall <package-id>
```text
After installing two tools, the manifest looks like:
```json
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "9.0.3",
"commands": [
"dotnet-ef"
]
},
"nbgv": {
"version": "3.7.112",
"commands": [
"nbgv"
]
}
}
}
```text
### Running Local Tools
```bash
# Run a local tool (long form)
dotnet tool run <command-name>
# Run a local tool (short form, when command starts with dotnet-)
dotnet <command-name>
# Examples
dotnet tool run dotnet-ef migrations add Init
dotnet ef migrations add Init # equivalent short form
```text
---
## Version Pinning and Team Workflows
The tool manifest enables reproducible tool versions across the team.
### Pinning Strategy
1. **One team member** creates the manifest and installs tools with specific versions
2. **Commit** `.config/dotnet-tools.json` to source control
3. **All team members** run `dotnet tool restore` after cloning or pulling
4. **Updates** are explicit: one person runs `dotnet tool update <package-id>`, commits the updated manifest
### Version Ranges
Use the `--version` option with NuGet version ranges for controlled flexibility:
```bash
# Exact version (strictest)
dotnet tool install <package-id> --version 2.0.1
# Allow patch updates (recommended for most tools)
dotnet tool install <package-id> --version "2.0.*"
# Pre-release versions
dotnet tool install <package-id> --version "*-preview*"
```text
The manifest always records the exact resolved version, ensuring all team members use identical versions after restore.
---
## CI Integration
### Tool Restore Before Build
In CI pipelines, restore tools before any build step that depends on them. Tool restore is fast and idempotent.
**GitHub Actions:**
```yaml