Setting up VS Code for .NET 10: the SDK, the C# extension's Roslyn language server and debugger, C# Dev Kit's Solution Explorer and Test Explorer, launch configuration and licensing.
First install the .NET 10 SDK, because VS Code does not bundle it. Then install C# Dev Kit, which brings in the C# extension. The C# extension gives you the Roslyn language server for IntelliSense, diagnostics and refactorings, plus the .NET debugger. C# Dev Kit adds the Visual Studio-style pieces: Solution Explorer, project templates and Test Explorer. You debug with the coreclr debugger, either auto-detected or configured in launch.json. C# Dev Kit is licensed like Visual Studio Community, so larger companies need a Visual Studio subscription.
"The first thing I do is install the .NET 10 SDK, because VS Code doesn't bundle it, and if the repo has a
global.jsonI install the version it asks for. Then I install C# Dev Kit, which brings the C# extension in with it.The two extensions do different jobs. The C# extension gives me the Roslyn language server for IntelliSense, diagnostics and refactorings, plus the .NET debugger. C# Dev Kit adds the Visual Studio-style pieces: Solution Explorer, project management and Test Explorer. For debugging I use the
coreclrdebugger type, either in alaunch.jsonwith apreLaunchTaskthat builds first, or straight from the project'slaunchSettings.jsonprofiles, and then I set breakpoints and step through as usual. I keep the extensions updated so the language server understands C# 14, and I commit.vscode/extensions.jsonso the whole team gets the same recommendations.Two things people miss. C# Dev Kit is licensed like Visual Studio Community, so a larger organisation needs a Visual Studio Professional or Enterprise subscription, or GitHub Codespaces. And I keep Workspace Trust on, because a cloned repo's
tasks.jsoncan run any command. The mistake I see most is expecting Solution Explorer and Test Explorer from the C# extension alone.My aim is a repo that works well in VS Code without depending on it, so launch profiles and CLI builds keep Visual Studio and Rider users just as productive."
dotnet --info. If the repo has a global.json, install the SDK it asks for, because the language server loads projects with that SDK.ms-dotnettools.csdevkit). It depends on the C# extension (ms-dotnettools.csharp) and the .NET Install Tool, which are installed with it.dotnet.defaultSolution in the workspace settings so the right one loads.launch.json and tasks.json yourself for full control..vscode/extensions.json so teammates are prompted to install the same extensions.| Piece | Provides |
|---|---|
| .NET SDK | dotnet CLI, MSBuild, compiler, runtime |
| C# extension | Roslyn language server (completion, squiggles, code fixes, navigation, source generator support, .editorconfig support), the .NET debugger |
| C# Dev Kit | Solution Explorer, add project / project reference, Test Explorer integration, project templates |
| .NET Install Tool | Acquires runtimes the extensions need |
Optional extensions round it out: the EditorConfig extension applies .editorconfig to non-C# files such as JSON and YAML, and the Dev Containers or WSL extensions provide remote environments. Code style and analyser rules for C# itself come from Roslyn and .editorconfig, so you do not need a separate C# linter.
The older OmniSharp-based language server can still be switched on by a setting, but the Roslyn language server is the default and the one to use.
The C# extension is open source, but its debugger may only be used with Microsoft products such as VS Code and Visual Studio. C# Dev Kit uses the same licence model as Visual Studio Community: free for individuals, academia, open-source development and the small non-enterprise teams Community allows. Other organisations need a qualifying Visual Studio Professional or Enterprise subscription (or GitHub Codespaces) for the developers who use it. Check with whoever manages licences before a company-wide rollout.
On a container-first team, developers used VS Code with C# Dev Kit and the Dev Containers extension. The repo committed extensions.json, a launch.json that started the API with ASPNETCORE_ENVIRONMENT=Development, and a tasks.json that ran dotnet build. A new starter on Linux could clone, open and press F5 on day one.
The interviewer wants to know whether you can be productive outside Visual Studio and understand what each component does.
Green flags
coreclr, preLaunchTask).Red flags
VS Code (UI process)
| JSON-RPC over the Language Server Protocol
v
Roslyn language server --> MSBuild design-time evaluation of each .csproj
| (references, analysers, source generators,
| compiler options per target framework)
v
completions, diagnostics, code fixes, Go to Definition
C# Dev Kit --> Solution Explorer, project system, Test Explorer (runs tests through the SDK)
Debugger <-- launch.json, or launchSettings.json profiles via C# Dev Kit
.NET Install Tool --> downloads runtimes the extensions themselves need
| Extension | Id | Provides | Licence |
|---|---|---|---|
| C# | ms-dotnettools.csharp |
Roslyn language server, debugger (vsdbg), .editorconfig and analyser support |
Open source; the debugger may only be used with Microsoft products |
| C# Dev Kit | ms-dotnettools.csdevkit |
Solution Explorer, add project/reference, templates, Test Explorer | Visual Studio Community terms |
| .NET Install Tool | ms-dotnettools.vscode-dotnet-runtime |
Acquires runtimes for the extensions | Free |
The extensions do not install the .NET SDK you build with. They use the SDK that dotnet resolves for the workspace folder, which honours global.json.
.sln, .slnx) or projects. With several solutions, dotnet.defaultSolution in .vscode/settings.json decides which one loads.dotnet restore if needed, then a design-time build per project and target framework.If IntelliSense is empty or wrong, the cause is almost always in steps 1–2: wrong SDK, failed restore (often a private feed needing credentials), or the wrong solution loaded. .NET: Restart Language Server reloads after you fix it.
launch.json describes debug sessions:
| Field | Meaning |
|---|---|
type |
coreclr for .NET (Core) and modern .NET apps on every platform |
request |
launch starts the program under the debugger; attach connects to a running process (processId, or ${command:pickProcess}) |
program |
Path to the built DLL, for example ${workspaceFolder}/src/Api/bin/Debug/net10.0/Api.dll |
cwd, env, args |
Working directory, environment variables and command-line arguments |
preLaunchTask |
A task from tasks.json that runs first, normally dotnet build |
serverReadyAction |
Opens the browser when an ASP.NET Core app prints its listening URL |
justMyCode |
Skip framework code when stepping (default true) |
tasks.json defines commands. The $msCompile problem matcher turns compiler output into clickable Problems entries.
With C# Dev Kit you can also skip launch.json: choose Run and Debug → C# and pick a project; for ASP.NET Core it launches from Properties/launchSettings.json profiles, which Visual Studio, Rider and dotnet run share.
| Organisation | C# extension and VS Code | C# Dev Kit |
|---|---|---|
| Individual, student, open source | Free | Free |
| Non-enterprise organisation within Community's user limits | Free | Free |
| Enterprise (more than 250 PCs or more than US$1 million revenue) | Free | Needs a Visual Studio Professional/Enterprise subscription or GitHub Codespaces |
Teams that can't use C# Dev Kit can still use the C# extension alone: IntelliSense and debugging work, but there is no Solution Explorer or Test Explorer.
The Remote – SSH, WSL and Dev Containers extensions run the language server and debugger on the remote machine or in the container, while the UI stays local. The SDK, extensions and NuGet cache live where the code lives, which gives a reproducible Linux toolchain for every developer.
dotnet.defaultSolution to a smaller solution or solution filter.bin/ and obj/ from file watching (files.watcherExclude) in very large repos.Workspace Trust opens unfamiliar folders in Restricted Mode, which disables tasks, debugging and some extension features until you trust the folder. Keep it on: a cloned repo's tasks.json can run any command. Install only extensions from trusted publishers, and use .vscode/extensions.json to recommend the approved set.
dotnet new webapi -n Api -o src/Api.launch.json and tasks.json from the code example and press F5.launch.json, use Run and Debug → C# instead, and compare.extensions.json, reopen the folder on another machine and accept the recommendation prompt.Install the extension from the command line:
code --install-extension ms-dotnettools.csdevkit
.vscode/extensions.json, committed so teammates get a prompt:
{
"recommendations": [
"ms-dotnettools.csdevkit",
"editorconfig.editorconfig"
]
}
.vscode/tasks.json:
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "process",
"command": "dotnet",
"args": ["build", "${workspaceFolder}/src/Api/Api.csproj"],
"problemMatcher": "$msCompile"
}
]
}
.vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch Api",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/src/Api/bin/Debug/net10.0/Api.dll",
"cwd": "${workspaceFolder}/src/Api",
"env": { "ASPNETCORE_ENVIRONMENT": "Development" },
"stopAtEntry": false
}
]
}
Mistake: installing VS Code without the .NET SDK, or without the SDK version global.json asks for.
The extensions don't include an SDK, so nothing builds and IntelliSense is empty.
Instead: install the SDK first and run dotnet --version in the repo folder to confirm it resolves; install the version global.json names.
Mistake: expecting Solution Explorer and Test Explorer from the C# extension alone. Those features come from C# Dev Kit, so people think the setup is broken. Instead: install C# Dev Kit (it brings the C# extension with it), or accept the C# extension alone if licensing rules out Dev Kit.
Mistake: ignoring C# Dev Kit licensing. It follows Visual Studio Community terms, so larger organisations can be out of compliance. Instead: check the organisation's size against Community's limits; above them, give C# Dev Kit users a Visual Studio Professional or Enterprise subscription, or use GitHub Codespaces.
Mistake: treating launch.json and launchSettings.json as the same thing.
launch.json is VS Code's own debugger configuration; launchSettings.json is the project's launch profile shared with Visual Studio, Rider and dotnet run. Keeping both in sync by hand leads to drift.
Instead: pick one approach per project. For ASP.NET Core, prefer launchSettings.json profiles so every IDE behaves the same.
Mistake: running old extension versions. An old Roslyn language server doesn't understand new C# syntax (C# 14 with .NET 10), so valid code shows errors. Instead: keep extensions on auto-update, and check the C# extension version when new syntax is flagged.
Mistake: hard-coding the program path and forgetting to update it after a framework upgrade.
After moving from net9.0 to net10.0, the debugger launches an old DLL or fails to find it.
Instead: update the path as part of the upgrade, or launch from launchSettings.json profiles, which don't need a DLL path.
Mistake: committing personal settings with absolute paths in .vscode/settings.json.
Paths like C:\Users\sam\... break on every other machine.
Instead: commit only team-wide settings using ${workspaceFolder}-relative paths, and keep personal settings in user settings.
Mistake: trusting every folder to avoid the Workspace Trust prompt.
A malicious repo's tasks, launch configurations or build scripts can then run code on your machine.
Instead: trust your organisation's repos (or a parent folder that holds them), and open anything from an unknown source in Restricted Mode first; read its .vscode/tasks.json, launch.json and build scripts, then trust it.
VS Code is strongest where the work is not only C#: Bicep, YAML pipelines, TypeScript front ends and container work all happen in one editor, and Remote development (SSH, WSL, Dev Containers) makes the environment reproducible. A senior engineer makes the repo work well in VS Code without making it depend on VS Code: launch profiles in launchSettings.json and builds through the CLI keep Visual Studio and Rider users equally productive.
On licensing, raise C# Dev Kit's terms with whoever manages software licences before a company-wide rollout; it is a common blind spot because VS Code itself is free.
Properties/launchSettings.json defines launch profiles for local development: how to start the app, which URLs, and which environment variables. Visual Studio, Rider, VS Code with C# Dev Kit and dotnet run all read it, but it is not published. In this file I would flag: secrets are committed (a production connection string and API key), so they must be rotated now and moved to user secrets; the environment is Production, which switches on production behaviour and turns off user secrets, and combined with the production connection string means a developer's F5 talks to the live database; and it binds to 0.0.0.0 over plain HTTP, exposing the app to the network. I would replace it with HTTPS and HTTP profiles on localhost using Development, and add a separate production-like profile only if someone needs to test production behaviour against non-production resources.
A breakpoint tells the debugger to pause the process when execution reaches a line, so I can look at variables and the call stack. I set one with F9 or a click in the gutter and start with F5. Then I step: Step Over (F10) runs the current line, Step Into (F11) goes into the method being called, and Step Out (Shift+F11) runs to the end of the current method and returns to the caller. Run to Cursor and Set Next Statement move faster or re-run a line. It works best on a Debug build with symbols, because optimised code can skip or reorder lines.
Last updated 1 Nov 2026.