.NET CLI Commands I Actually Use
Development Tech

.NET CLI Commands I Actually Use

A practical guide from daily development experience

Visual Studio handles most .NET tasks well, but I keep reaching for the CLI in certain situations: scaffolding new projects, managing dependencies in scripts, working on remote machines, or when I just want something done quickly without navigating menus.

This guide covers the commands I use regularly. It's not comprehensive—the --help flag and official documentation serve that purpose—but rather a collection of practical commands with real-world context.

Quick Diagnostics

When something isn't working, start here.

dotnet --version

This shows the active SDK version. If C# language features aren't available or builds fail unexpectedly, version mismatch is often the culprit.

For more detail:

dotnet --info

This displays all installed SDKs and runtimes, the current architecture, and environment information. Useful when troubleshooting CI/CD pipelines or helping teammates debug their setup.

Project Templates

Listing Available Templates

Lists all installed project templates with their short names.

dotnet new list

The output shows template names, short identifiers, and tags. The short name is what you'll use to create projects.

Creating New Projects

Creates a new project. The -n flag specifies the project name; without it, the current directory name is used.

dotnet new console -n MyConsoleApp
dotnet new webapi -n MyApi
dotnet new classlib -n MyLibrary
dotnet new xunit -n MyTests

Templates I use most:

  • console — Quick utilities and testing ideas
  • webapi — REST API projects
  • classlib — Shared libraries
  • xunit — Unit test projects
  • sln — Solution files

Solution Management

Creating and Wiring Up Solutions

You can scaffold an entire project structure from the command line:

dotnet new sln -n MyApp
dotnet new webapi -n MyApp.Api
dotnet new classlib -n MyApp.Core
dotnet new xunit -n MyApp.Tests
dotnet sln add MyApp.Api MyApp.Core MyApp.Tests

Listing Projects in a Solution

Shows all projects in a solution. Useful for scripting and understanding unfamiliar codebases.

dotnet sln list

Removing Projects from a Solution

Removes a project from a solution without deleting the project files.

dotnet sln remove MyApp.OldProject/MyApp.OldProject.csproj

Package Management

Adding and Removing Packages

Manages NuGet package references.

dotnet add package Newtonsoft.Json
dotnet add package Newtonsoft.Json --version 13.0.1
dotnet remove package Newtonsoft.Json

When searching for packages, nuget.org provides the exact command syntax including version numbers.

Restoring Packages

Downloads all NuGet packages specified in project files.

dotnet restore

Modern .NET runs this automatically before builds, but explicit restoration is useful after cloning repositories or editing project files manually. It's often the first troubleshooting step when builds fail unexpectedly.

Understanding Package Dependencies

Shows the dependency chain explaining why a package is included. Introduced in .NET 7.

dotnet nuget why MyProject.csproj Newtonsoft.Json

Output:

Project 'MyProject' has the following dependency graph(s) for 'Newtonsoft.Json':

   MyProject
   → PackageA 2.1.0
     → Newtonsoft.Json 13.0.1

This is valuable for investigating security vulnerabilities in transitive dependencies, understanding version conflicts, and determining if a package can be safely removed.

Project References

Adding and Removing References

Manages references between projects in a solution. Run this from within the project directory that needs the reference:

dotnet add reference ../MyApp.Core/MyApp.Core.csproj

Useful when scaffolding multi-project solutions:

cd MyApp.Api
dotnet add reference ../MyApp.Core/MyApp.Core.csproj
cd ../MyApp.Tests
dotnet add reference ../MyApp.Core/MyApp.Core.csproj

Listing References

Shows all project references for the current project. Helpful in large solutions when understanding the dependency graph.

dotnet list reference

Development Workflow

Watching for Changes

Watches for file changes and automatically rebuilds/reruns. This is one of the most useful commands for active development.

dotnet watch run

For test-driven development:

dotnet watch test

The feedback loop is much tighter than manually rebuilding after each change.

Cleaning Build Outputs

Removes all build outputs from bin and obj directories.

dotnet clean

Useful when build caching causes issues or when you want a guaranteed clean state.

Development Certificates

Managing HTTPS Certificates

Manages HTTPS certificates for local development. Behaviour varies by platform.

Windows and macOS:

dotnet dev-certs https --trust

This generates and trusts a development certificate. You may be prompted for administrator access or keychain password.

Linux:

Certificate management is more involved due to distribution differences. The command generates certificates, but trusting them system-wide requires manual steps.

Generate the certificate:

dotnet dev-certs https -ep ~/.aspnet/https/aspnetapp.pfx -p password

On Ubuntu/Debian:

sudo cp ~/.aspnet/https/aspnetapp.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates

On Fedora/RHEL:

sudo cp ~/.aspnet/https/aspnetapp.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust

To start fresh, remove existing certificates and trust a new one:

dotnet dev-certs https --clean
dotnet dev-certs https --trust

Secret Management

Managing User Secrets

Manages sensitive configuration during local development without committing secrets to source control.

Initialise for the project:

dotnet user-secrets init

Set a secret:

dotnet user-secrets set "ApiKey" "your-key-here"

List all secrets:

dotnet user-secrets list

Remove a secret:

dotnet user-secrets remove "ApiKey"

Clear all secrets:

dotnet user-secrets clear

Secrets are stored in your user profile directory, separate from the project. For production, use proper secret management solutions or environment variables.

SDK Version Pinning

Using global.json

Pins the .NET SDK version for a project or directory tree. Essential for team consistency and CI/CD pipelines.

dotnet new globaljson --sdk-version 8.0.100

This creates:

{
  "sdk": {
    "version": "8.0.100"
  }
}

The file affects all projects in the same directory and subdirectories. This prevents "works on my machine" issues caused by SDK differences.

For flexibility with newer patch versions:

{
  "sdk": {
    "version": "8.0.100",
    "rollForward": "latestPatch"
  }
}

Global Tools

Installing and Managing Tools

.NET global tools are command-line utilities distributed via NuGet.

Install a tool globally:

dotnet tool install --global dotnet-ef

List installed tools:

dotnet tool list --global

Update a tool:

dotnet tool update --global dotnet-ef

Uninstall a tool:

dotnet tool uninstall --global dotnet-ef

Tools Worth Installing

Entity Framework Core — Migrations and database updates:

dotnet tool install --global dotnet-ef
dotnet ef migrations add InitialCreate
dotnet ef database update

Outdated Package Checker — Identifies outdated package references:

dotnet tool install --global dotnet-outdated-tool
dotnet outdated

Code Formatter — Applies consistent formatting:

dotnet tool install --global dotnet-format
dotnet format

Simple HTTP Server — For serving static content:

dotnet tool install --global dotnet-serve
dotnet serve -p 8080

Performance Counters — Real-time metrics:

dotnet tool install --global dotnet-counters
dotnet counters monitor --process-id <PID>

Solution File Migration

Migrating to the New Format

Microsoft introduced a new solution file format (.slnx) that's more readable than the traditional .sln format.

dotnet sln migrate MySolution.sln

This creates a new .slnx file alongside the original—manual cleanup is needed afterwards. Currently dotnet new sln still creates the traditional format, though this will likely change.

Troubleshooting

SDK Version Mismatches

Problem: Features aren't available or builds fail with cryptic errors.

Solution: Check your SDK version with dotnet --version and verify it matches project requirements. Use global.json to enforce consistent versions.

Path Issues with Project References

Problem: Reference commands fail with "could not find project" errors.

Solution: Use forward slashes for cross-platform compatibility.

Works everywhere:

dotnet add reference ../MyLib/MyLib.csproj

Windows-only:

dotnet add reference ..\MyLib\MyLib.csproj

Restoration Failures

Problem: Package restoration fails unexpectedly.

Solution: Check network connectivity and NuGet feed configuration. Clear the cache if corruption is suspected:

dotnet nuget locals all --clear

Certificate Trust Issues

Problem: HTTPS warnings persist after trusting certificates.

Solution: On Windows and macOS, ensure you have appropriate permissions. On Linux, follow distribution-specific procedures. Browsers may cache certificate issues—try restarting.

Stale Build Artifacts

Problem: Changes don't appear after rebuilding.

Solution: Clean before building:

dotnet clean
dotnet build

Or delete bin and obj folders manually if issues persist.

Why Bother with the CLI?

The CLI complements rather than replaces IDEs. Visual Studio and Rider excel at debugging, refactoring, and code navigation. The CLI is better for:

  • Scripting and automation — CI/CD pipelines, project generators, repetitive tasks
  • Reproducibility — Commands in scripts execute consistently; GUI workflows are harder to document
  • Remote development — SSH sessions make GUIs impractical
  • Speed — Once familiar, typing is often faster than navigating menus
  • Cross-platform consistency — Same interface on Windows, macOS, and Linux

Start with a few commands and expand gradually. Even basic use makes repetitive tasks more efficient.


Quick Reference

Project Creation

dotnet --version
dotnet --info
dotnet new list
dotnet new console -n MyApp
dotnet new webapi -n MyApi
dotnet new classlib -n MyLib
dotnet new xunit -n MyTests
dotnet new sln -n MySolution
dotnet new globaljson --sdk-version 8.0.100

Solution Management

dotnet sln add Project/Project.csproj
dotnet sln remove Project.csproj
dotnet sln list
dotnet sln migrate MySolution.sln

Package Management

dotnet add package PackageName
dotnet add package PackageName --version 1.0.0
dotnet remove package PackageName
dotnet restore
dotnet nuget why Project.csproj PackageName
dotnet nuget locals all --clear

Project References

dotnet add reference ../Other/Other.csproj
dotnet remove reference Other.csproj
dotnet list reference

Build and Run

dotnet build
dotnet run
dotnet watch run
dotnet test
dotnet watch test
dotnet clean
dotnet publish -c Release

Development Tools

dotnet dev-certs https --trust
dotnet dev-certs https --clean
dotnet user-secrets init
dotnet user-secrets set "Key" "Value"
dotnet user-secrets list

Global Tools

dotnet tool install --global dotnet-ef
dotnet tool install --global dotnet-outdated-tool
dotnet tool install --global dotnet-format
dotnet tool install --global dotnet-serve
dotnet tool list --global
dotnet tool update --global tool-name

Troubleshooting Sequence

dotnet --version
dotnet clean
dotnet nuget locals all --clear
dotnet restore
dotnet build

Version Requirements

Some commands require specific SDK versions:

  • dotnet nuget why — .NET 7.0+
  • dotnet sln migrate — .NET 9.0+
  • dotnet watch — Available since .NET Core 2.1, improved in later versions

Check the official documentation for current command availability.

Back to blog