Build Your First VS Code Extension: A Step‑by‑Step Tutorial
This tutorial walks developers through the complete process of creating a simple Visual Studio Code extension—from installing Node.js, Git, and Yeoman, to generating project scaffolding, configuring package.json, writing activation code, adding commands and menu items, and testing the extension—while highlighting VS Code's multi‑process architecture and extension limitations.
Introduction
Visual Studio Code (VS Code) is a popular, open‑source editor built with TypeScript and Electron. It has over 115k stars on GitHub and a lightweight design that supports many languages through a modular extension system.
Project repository: https://github.com/microsoft/vscode
VS Code Architecture
VS Code runs with several processes:
Main process – handles window management, inter‑process communication, and auto‑updates.
Renderer process – renders the web UI.
Extension host process – runs each extension in an isolated Node.js environment.
Debug process – provides debugging capabilities.
Language services – supply IntelliSense, diagnostics, and navigation for many languages.
Environment Preparation
Install Node.js and Git, then install Yeoman and the VS Code Extension Generator globally: npm install -g yo generator-code Successful installation is confirmed by the command‑line output.
Initialize the Extension Project
Run the generator to scaffold a new extension: yo code The generator asks a series of questions. For this tutorial choose the JavaScript option (the second choice) and fill in the requested fields such as extension name, identifier, description, and package manager.
Project Structure and Configuration
The generated package.json contains key fields:
{
"name": "test-extension",
"displayName": "test-extension",
"description": "vscode extension sample",
"version": "0.0.1",
"engines": { "vscode": "^1.52.0" },
"categories": ["Other"],
"activationEvents": ["onCommand:test-extension.helloWorld"],
"main": "./extension.js",
"contributes": {
"commands": [{
"command": "test-extension.helloWorld",
"title": "Hello World"
}]
},
"scripts": {
"lint": "eslint .",
"pretest": "npm run lint",
"test": "node ./test/runTest.js"
},
"devDependencies": {
"@types/vscode": "^1.55.0",
"@types/glob": "^7.1.3",
"@types/mocha": "^8.0.4",
"@types/node": "^12.11.7",
"eslint": "^7.19.0",
"glob": "^7.1.6",
"mocha": "^8.2.1",
"typescript": "^4.1.3",
"vscode-test": "^1.5.0"
}
}Adjust the engines.vscode version if your VS Code is older (e.g., change to ^1.52.0).
Extension Entry Point
The generated extension.js defines two lifecycle functions:
// Import the VS Code API
const vscode = require('vscode');
/**
* @param {vscode.ExtensionContext} context
*/
function activate(context) {
console.log('Congratulations, your extension "test-extension" is now active!');
let disposable = vscode.commands.registerCommand('test-extension.helloWorld', function () {
vscode.window.showInformationMessage('Hello World from test-extension!');
});
context.subscriptions.push(disposable);
}
function deactivate() {}
module.exports = { activate, deactivate };The activate function registers a command that shows an information message; deactivate is called when the extension is unloaded.
Adding a Custom Button via Menus
To add a button to the editor title bar, modify package.json:
"activationEvents": ["*"],
"contributes": {
"commands": [
{ "command": "test.button", "title": "按钮", "icon": { "light": "./media/light/preview.svg", "dark": "./media/dark/preview.svg" } }
],
"menus": {
"editor/title": [{ "command": "test.button", "group": "navigation" }]
}
}Then extend extension.js to register the new command:
function activate(context) {
console.log('我在这里!!');
let disposable = vscode.commands.registerCommand('test-extension.helloWorld', function () {
vscode.window.showInformationMessage('我改变了 command 的名字!');
});
let button = vscode.commands.registerCommand('test.button', function () {
vscode.window.showInformationMessage('按钮点击');
});
context.subscriptions.push(disposable, button);
}Now the button appears in the editor title bar and shows a message when clicked.
Menu Visibility Conditions
You can restrict the button to JavaScript files using a when clause:
"menus": {
"editor/title": [{
"command": "test.button",
"group": "navigation",
"when": "resourceLangId == javascript"
}]
}The group property controls ordering; navigation has the highest priority.
Summary and Limitations
VS Code extensions let you add commands, menus, and UI elements within a well‑defined sandbox. Extensions cannot directly manipulate the VS Code DOM or inject arbitrary CSS/HTML, which ensures UI stability, prevents breakage from underlying web‑technology changes, and keeps user interactions predictable.
While this guide covers only a small portion of the extension API, it demonstrates the core workflow: set up the environment, scaffold a project, configure package.json, write activation code, and test the result.
Future topics may explore language‑server features such as auto‑completion and diagnostics.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Liangxu Linux
Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
