yo codeDeveloping VSCode extensions starts with the creation of a standardized project structure. Microsoft provides a generator tool based on Yeoman, which automates the setup of TypeScript projects, build configurations, and debugging environments.
Extension development requires Node.js as a runtime environment.
Node.js provides both the npm package manager and the
JavaScript runtime needed for TypeScript transpilation and extension
hosting.
The required tools are installed globally:
npm install -g yo generator-codeThis installation provides two components:
yo: The Yeoman command-line tool for scaffolding
operationsgenerator-code: The VSCode-specific generator with
project templatesThe command yo code starts an interactive dialog for
project configuration. The selection is made via a menu with various
extension types:
For extension development, “New Extension (TypeScript)” is the default choice. The dialog then asks for:
After completing the configuration, the generator creates the following directory structure:
extension-name/
├── .vscode/
│ ├── launch.json # Debugger configuration
│ ├── settings.json # Workspace settings
│ └── tasks.json # Build tasks
├── src/
│ ├── extension.ts # Extension entry point
│ └── test/
│ └── extension.test.ts # Unit tests
├── package.json # Extension manifest
├── tsconfig.json # TypeScript configuration
├── .gitignore # Git exclusions
├── .eslintrc.json # Linting rules
├── README.md # Documentation
└── CHANGELOG.md # Version history
The package.json defines extension metadata and
contributions:
{
"name": "extension-name",
"displayName": "Extension Name",
"description": "Extension Description",
"version": "0.0.1",
"engines": {
"vscode": "^1.74.0"
},
"categories": ["Other"],
"activationEvents": [],
"main": "./out/extension.js",
"contributes": {
"commands": [{
"command": "extension-name.helloWorld",
"title": "Hello World"
}]
},
"scripts": {
"vscode:prepublish": "npm run compile",
"compile": "tsc -p ./",
"watch": "tsc -watch -p ./"
},
"devDependencies": {
"@types/vscode": "^1.74.0",
"@types/node": "16.x",
"typescript": "^4.9.4"
}
}The generated extension.ts contains the required
lifecycle functions:
import * as vscode from 'vscode';
export function activate(context: vscode.ExtensionContext) {
const disposable = vscode.commands.registerCommand(
'extension-name.helloWorld',
() => {
vscode.window.showInformationMessage('Hello World from Extension Name!');
}
);
context.subscriptions.push(disposable);
}
export function deactivate() {}The .vscode/launch.json file defines the debugging
environment:
{
"version": "0.2.0",
"configurations": [
{
"name": "Run Extension",
"type": "extensionHost",
"request": "launch",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
],
"outFiles": [
"${workspaceFolder}/out/**/*.js"
],
"preLaunchTask": "${workspaceFolder}/npm: watch"
}
]
}This configuration:
Debugging starts via F5 or the debug panel. VSCode opens a new instance titled “[Extension Development Host]”. In this environment, the developed extension is active and available via the command palette (Ctrl+Shift+P).
The generated Hello World command can be executed under the name “Hello World” and displays an information message.
The TypeScript compiler transpiles source files from
src/ to out/. The configuration in
tsconfig.json defines:
{
"compilerOptions": {
"module": "commonjs",
"target": "ES2020",
"outDir": "out",
"lib": ["ES2020"],
"sourceMap": true,
"rootDir": "src",
"strict": true
},
"exclude": ["node_modules", ".vscode-test"]
}During development, the compiler can be run in watch mode via
npm run watch. Changes are automatically transpiled and
become available in the development host instance upon reload
(Ctrl+R).
The generated project forms the foundation for more complex extensions. Typical extensions include:
src/resources/
directoryThe project structure remains consistent and follows the conventions of VSCode extension development.