To build a VS Code extension, scaffold a project with the Yeoman generator, press F5 to launch an Extension Development Host, and declare features in package.json as contribution points. Keep the dependency tree small, request only what you need, and remember that your extension runs with the user's privileges.
How do you create the first extension?
The official tutorial needs Node.js and Git. You scaffold a TypeScript or JavaScript project with Yeoman and the VS Code Extension Generator, either by running it once with npx or by installing it globally. The generator asks what type of extension you want, a name, an identifier and a description, whether to start a git repository, which bundler to use and which package manager.
Open src/extension.ts and press F5, or run Debug: Start Debugging from the Command Palette. VS Code compiles the extension and launches a second window called the Extension Development Host. Run the Hello World command there and you see a notification. If the command does not appear, the tutorial says to check that the engines.vscode value in package.json is compatible with your installed VS Code.
What is a contribution point?
Contribution points are static declarations in the extension manifest, package.json, that extend VS Code. They add commands, menus and keybindings. Because they are declared and not discovered at run time, a reader can see what an extension adds to the editor by opening one file.
The manifest is also where an extension states which VS Code versions it supports. Keep that range honest and test against the oldest version you claim.
How do you debug it?
Built in debugging works on extensions. Set a breakpoint in the gutter, and VS Code stops there when your code runs in the development host. You can hover over variables, use the Run and Debug view, and evaluate expressions in the Debug Console. After code changes, run Developer: Reload Window in the host to see them.
Why does security matter for an extension?
An extension is code that runs on a developer's machine, next to source code, tokens and terminals. That makes it a valuable target and a real responsibility. Your users trust you with their editor, and your dependencies inherit that trust.
Three habits keep the risk down.
- Keep dependencies few. Everything in your package tree ships with your extension and runs for your users.
- Do not read or send more than the feature needs. If you collect data, say exactly what and why.
- Protect your publisher account and your build pipeline, because a stolen publish credential lets an attacker push an update to every installed copy.
A constructed example
A developer writes an extension that formats SQL files. The first version pulls in a large utility library for one string function and bundles two logging packages. A reviewer points out that this adds over a hundred indirect packages to a tool that only needs a formatter. The developer swaps in a few lines of local code and drops the logging packages. The published extension is smaller, starts faster, and exposes far less to a supply chain problem.
How to check or apply this
- Scaffold with the official generator, and run it in the Extension Development Host.
- Read your package.json contribution points and remove any that you do not use.
- Set a truthful engines.vscode range and test at the low end.
- Audit dependencies before each release and remove any you can replace cheaply.
- Commit your lockfile and install in CI from it.
- Use multi-factor authentication on the publisher account and keep publish tokens out of repositories.
- Document what data the extension touches.
Safeguard offers its own IDE extensions, and its dependency scanning can check an extension project's tree before you publish. The free scan at gold.safeguard.sh/scan covers up to 100 dependencies.
Quick check
What does F5 do in the tutorial?
It compiles the extension and opens a new Extension Development Host window where you can run and debug it.
Where do I declare commands and menus?
In the extension manifest, package.json, as contribution points.
Sources
Last reviewed: 18 October 2026.