📁 Sangam Dhakal - Portfolio v2.0 - Netscape Navigator 4.0
_
□
×

📚 Interview question

How do you set up Visual Studio Code for C# and .NET development, and what do the C# extension and C# Dev Kit each provide?

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.

Junior Theory Beginner csharp-dev-kit debugging developer-tooling ide vscode

🎯 Key points

  • Install a supported .NET SDK first; VS Code does not include it, and the extensions need an SDK that matches the project
  • The C# extension (ms-dotnettools.csharp) provides the Roslyn language server and the .NET debugger
  • C# Dev Kit (ms-dotnettools.csdevkit) adds Solution Explorer, project management and Test Explorer
  • C# Dev Kit follows Visual Studio Community licence terms: free for individuals, academia, open source and small teams; other organisations need a Visual Studio Professional/Enterprise subscription or GitHub Codespaces
  • Debugging uses the coreclr debugger type, configured in launch.json or launched from launchSettings.json profiles
  • Keep extensions updated so they understand the current C# version
  • Share recommended extensions with .vscode/extensions.json and use Workspace Trust for unfamiliar repos

⏱ 30-second answer

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.

🗣 Full answer (senior)

How I would answer this in an interview

"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.json I 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 coreclr debugger type, either in a launch.json with a preLaunchTask that builds first, or straight from the project's launchSettings.json profiles, 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.json so 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.json can 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."


Step by step

  1. Install the .NET SDK (10.0 for current LTS work). Check with dotnet --info. If the repo has a global.json, install the SDK it asks for, because the language server loads projects with that SDK.
  2. Install C# Dev Kit (ms-dotnettools.csdevkit). It depends on the C# extension (ms-dotnettools.csharp) and the .NET Install Tool, which are installed with it.
  3. Open the folder that contains your solution or project. C# Dev Kit loads it into Solution Explorer. If the folder has several solutions, set dotnet.defaultSolution in the workspace settings so the right one loads.
  4. Run and debug with F5. VS Code can generate configuration, or you write launch.json and tasks.json yourself for full control.
  5. Commit .vscode/extensions.json so teammates are prompted to install the same extensions.
  6. Keep the extensions updated. A new C# language version (C# 14 with .NET 10) needs a C# extension release whose Roslyn understands it.

Who does what

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.

Licensing

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.

Production example

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.

🔍 What the interviewer is checking

The interviewer wants to know whether you can be productive outside Visual Studio and understand what each component does.

Green flags

  • Separates the SDK, C# extension and C# Dev Kit responsibilities.
  • Knows how debugging is configured (coreclr, preLaunchTask).
  • Mentions licensing and Workspace Trust.

Red flags

  • Thinks VS Code includes the SDK.
  • Cannot explain why IntelliSense might fail (no restore, wrong SDK).
  • Treats extensions as risk-free.

📚 Learn in depth

1. The pieces and how they talk

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.

2. How a workspace loads

  1. VS Code opens the folder. C# Dev Kit looks for solution files (.sln, .slnx) or projects. With several solutions, dotnet.defaultSolution in .vscode/settings.json decides which one loads.
  2. The language server runs dotnet restore if needed, then a design-time build per project and target framework.
  3. Diagnostics appear in the Problems panel; load errors appear in View → Output → C# (and C# Dev Kit).

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.

3. Debugging in depth

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.

4. Licensing in practice

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.

5. Remote and container development

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.

6. Performance

  • Large solutions: open a sub-folder or set dotnet.defaultSolution to a smaller solution or solution filter.
  • Analysers and source generators run in the language server; a slow generator makes typing slow.
  • Exclude bin/ and obj/ from file watching (files.watcherExclude) in very large repos.

7. Security

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.

8. Try it yourself

  1. Install C# Dev Kit and run dotnet new webapi -n Api -o src/Api.
  2. Add the launch.json and tasks.json from the code example and press F5.
  3. Set a breakpoint in an endpoint, call it, and inspect variables.
  4. Remove launch.json, use Run and Debug → C# instead, and compare.
  5. Add extensions.json, reopen the folder on another machine and accept the recommendation prompt.
  6. Break restore on purpose (add a non-existent package) and find the error in the C# output pane.

💻 Code

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
    }
  ]
}

⚠ Common mistakes

  • 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.

🏛 Senior insight: trade-offs

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.

🔗 Follow-ups the interviewer may ask

  1. When: The candidate says C# Dev Kit can launch from launchSettings.json. Why: Launch profiles are shared by every IDE and dotnet run, and are a common place for leaked secrets.
    How to answer

    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.

  2. When: The candidate mentions launch.json or pressing F5 in VS Code. Why: Checks the debugging basics that work the same way in every editor.
    How to answer

    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.

↩ Usually asked after

More in IDEs and Editors

Last updated 1 Nov 2026.

🌐 Sangam's Webring

⏪ Previous 🏠 Main Next ⏩
💬 Chat with me