Extension API
Topics Overview Your First Extension Extension Anatomy Wrapping Up Overview Common Capabilities Theming Extending Workbench Overview AI Extensibility Language Model Tool MCP Dev Guide Chat Participant Chat Tutorial Language Model Language Model Tutorial Language Model Chat Provider Prompt TSX Command Color Theme File Icon Theme Product Icon Theme Tree View Webview Notebook Custom Editors Virtual Documents Virtual Workspaces Web Extensions Workspace Trust Task Provider Source Control Debugger Extension Markdown Extension Test Extension Custom Data Extension Telemetry Overview Activity Bar Sidebars Panel Status Bar Views Editor Actions Quick Picks Command Palette Notifications Webviews Context Menus Walkthroughs Settings Overview Syntax Highlight Guide Semantic Highlight Guide Snippet Guide Language Configuration Guide Programmatic Language Features Language Server Extension Guide Embedded Languages Testing Extensions Publishing Extensions Bundling Extensions Continuous Integration Extension Host Remote Development and Codespaces Using Proposed API Migrate from TSLint to ESLint Python Extension Template VS Code API Contribution Points Activation Events Extension Manifest Built-In Commands When Clause Contexts Theme Color Product Icon Reference Document SelectorContribution Points
Contribution Points are a set of JSON declarations that you make in the contributes field of the package.json Extension Manifest. Your extension registers Contribution Points to extend various functionalities within Visual Studio Code. Here is a list of all available Contribution Points:
- authentication
- breakpoints
- chatInstructions
- chatPromptFiles
- chatSkills
- colors
- commands
- configuration
- configurationDefaults
- customEditors
- debuggers
- grammars
- icons
- iconThemes
- jsonValidation
- keybindings
- languages
- menus
- problemMatchers
- problemPatterns
- productIconThemes
- resourceLabelFormatters
- semanticTokenModifiers
- semanticTokenScopes
- semanticTokenTypes
- snippets
- submenus
- taskDefinitions
- terminal
- themes
- typescriptServerPlugins
- views
- viewsContainers
- viewsWelcome
- walkthroughs
contributes.authentication
Contributes an authentication provider. This will set up an activation event for your provider and display it in your extension's features.
{ "contributes": { "breakpoints": [ { "language": "javascript" }, { "language": "javascriptreact" } ] } }contributes.chatInstructions
Contributes instructions files for Copilot Chat. Instructions files provide custom guidelines that are automatically included in chat requests to steer the behavior of Copilot. Use this contribution point to bundle reusable instructions with your extension, such as coding conventions, framework-specific guidelines, or domain-specific rules.
Copilot automatically applies contributed instructions when the user's chat request is relevant to the instructions' use case. You do not need to manually attach them.
Each entry requires a path to a Markdown file relative to the extension root. You can optionally specify a when clause to control when the instructions are enabled. Specify the name and description metadata inside the Markdown file itself rather than in the contribution point.
{ "contributes": { "chatInstructions": [ { "path": "./prompts/textMateGuidelines.instructions.md", "when": "resourceExtname == .tmLanguage" } ] } }chatInstructions properties
| path | string | Yes | Path to the Markdown file relative to the extension root. The path must resolve to a location inside the extension. |
| when | string | No | A when clause condition that must be true for this entry to be enabled. |
See the chatPromptFiles contribution point for contributing reusable prompt files.
contributes.chatPromptFiles
Contributes prompt files for Copilot Chat. Prompt files are reusable chat prompts that users can invoke as slash commands in chat. Use this contribution point to bundle ready-made prompts with your extension.
Each entry requires a path to a Markdown file relative to the extension root. You can optionally specify a when clause to conditionally enable the prompt. Specify the name and description metadata inside the Markdown file itself rather than in the contribution point.
{ "contributes": { "chatSkills": [ { "path": "./skills/my-skill/SKILL.md" } ] } }chatSkills properties
| path | string | Yes | Path to the SKILL.md file relative to the extension root. The path must resolve to a location inside the extension, and the parent directory name must match the name field in SKILL.md. |
| when | string | No | A when clause condition that must be true for this entry to be enabled. |
See Contribute skills from extensions for the required skill structure and SKILL.md format.
contributes.colors
Contributes new themable colors. These colors can be used by the extension in editor decorators and in the status bar. Once defined, users can customize the color in the workspace.colorCustomization setting and user themes can set the color value.
const errorColor = new vscode.ThemeColor('superstatus.error');contributes.commands
Contribute the UI for a command consisting of a title and (optionally) an icon, category, and enabled state. Enablement is expressed with when clauses. By default, commands show in the Command Palette (⇧⌘P (Windows, Linux Ctrl+Shift+P)) but they can also show in other menus.
Presentation of contributed commands depends on the containing menu. The Command Palette, for instance, prefixes commands with their category, allowing for easy grouping. However, the Command Palette doesn't show icons nor disabled commands. The editor context menu, on the other hand, shows disabled items but doesn't show the category label.
Note: When a command is invoked (from a key binding, from the Command Palette, any other menu, or programmatically), VS Code will emit an activationEvent onCommand:${command}.
Note: When using icons from product icons, setting light and dark will disable the icon. The correct syntax is "icon": "$(book)"
command example
{ "contributes": { "configuration": { "title": "Settings Editor Test Extension", "type": "object", "properties": { "settingsEditorTestExtension.booleanExample": { "type": "boolean", "default": true, "description": "Boolean Example" }, "settingsEditorTestExtension.stringExample": { "type": "string", "default": "Hello World", "description": "String Example" } } } } }You can read these values from your extension using vscode.workspace.getConfiguration('myExtension').
Configuration schema
Your configuration entry is used both to provide intellisense when editing your settings in the JSON editor, and to define the way they appear in the settings UI.
title
The title 1️⃣️ of a category is the heading used for that category.
{ "gitMagic.blame.heatMap.enabled": { "description": "Specifies whether to provide a heatmap indicator in the gutter blame annotations" } }If you use markdownDescription instead of description, your setting description will be parsed as Markdown in the settings UI.
{ "gitMagic.views.pageItemLimit": { "type": "number", "default": 20, "markdownDescription": "Specifies the number of items to show in each page when paginating a view list. Use 0 to specify no limit" } }A string setting can be rendered with a multiline text input if it sets "editPresentation": "multilineText" on the configuration entry.
For boolean entries, the markdownDescription (or description if markdownDescription is not specified) will be used as the label next to the checkbox.
{ "settingsEditorTestExtension.enumSetting": { "type": "string", "enum": ["first", "second", "third"], "markdownEnumDescriptions": [ "The *first* enum", "The *second* enum", "The *third* enum" ], "enumItemLabels": ["1st", "2nd", "3rd"], "default": "first", "description": "Example setting with an enum" } }deprecationMessage / markdownDeprecationMessage
If you set deprecationMessage, or markdownDeprecationMessage, the setting will get a warning underline with your specified message. Also, the setting will be hidden from the settings UI unless it is configured by the user. If you set markdownDeprecationMessage, the markdown will not be rendered in the setting hover or the problems view. If you set both properties, deprecationMessage will be shown in the hover and the problems view, and markdownDeprecationMessage will be rendered as Markdown in the settings UI.
Example:
{ "contributes": { "configuration": { "title": "Git", "properties": { "git.alwaysSignOff": { "type": "boolean", "scope": "resource", "default": false, "description": "%config.alwaysSignOff%" }, "git.ignoredRepositories": { "type": "array", "default": [], "scope": "window", "description": "%config.ignoredRepositories%" }, "git.autofetch": { "type": ["boolean", "string"], "enum": [true, false, "all"], "scope": "resource", "markdownDescription": "%config.autofetch%", "default": false, "tags": ["usesOnlineServices"] } } } } }You can see that git.alwaysSignOff has resource scope and can be set per user, workspace, or folder, while the ignored repositories list with window scope applies more globally for the VS Code window or workspace (which might be multi-root).
ignoreSync
You can set ignoreSync to true to prevent the setting from being synchronized with the user's settings. This is useful for settings that are not user-specific. For example, the remoteTunnelAccess.machineName setting is not user-specific and should not be synchronized. Please note that if you have set the scope to machine or machine-overridable, the setting will not be synchronized regardless of the value of ignoreSync.
"files.autoSaveDelay": { "markdownDescription": "Controls the delay in ms after which a dirty editor is saved automatically. Only applies when `#files.autoSave#` is set to `afterDelay`.", // ... }In the settings UI, this is rendered as:
contributes.configurationDefaults
Contribute default values for other registered configurations and override their defaults.
The following example overrides the default behavior of files.autoSave setting to AutoSave files on focus change.
{ "contributes": { "configurationDefaults": { "[markdown]": { "editor.wordWrap": "on", "editor.quickSuggestions": { "comments": "off", "strings": "off", "other": "off" } } } } }contributes.customEditors
The customEditors contribution point is how your extension tells VS Code about the custom editors that it provides. For example, VS Code needs to know what types of files your custom editor works with as well as how to identify your custom editor in any UI.
Here's a basic customEditor contribution for the custom editor extension sample:
{ "contributes": { "debuggers": [ { "type": "node", "label": "Node Debug", "program": "./out/node/nodeDebug.js", "runtime": "node", "languages": ["javascript", "typescript", "javascriptreact", "typescriptreact"], "configurationAttributes": { "launch": { "required": ["program"], "properties": { "program": { "type": "string", "description": "The program to debug." } } } }, "initialConfigurations": [ { "type": "node", "request": "launch", "name": "Launch Program", "program": "${workspaceFolder}/app.js" } ], "configurationSnippets": [ { "label": "Node.js: Attach Configuration", "description": "A new configuration for attaching to a running node program.", "body": { "type": "node", "request": "attach", "name": "${2:Attach to Port}", "port": 9229 } } ], "variables": { "PickProcess": "extension.node-debug.pickNodeProcess" } } ] } }For a full walkthrough on how to integrate a debugger, go to Debugger Extension.
contributes.grammars
Contribute a TextMate grammar to a language. You must provide the language this grammar applies to, the TextMate scopeName for the grammar and the file path.
Note: The file containing the grammar can be in JSON (filenames ending in .json) or in XML plist format (all other files).
grammar example
{ "contributes": { "icons": { "distro-ubuntu": { "description": "Ubuntu icon", "default": { "fontPath": "./distroicons.woff", "fontCharacter": "\\E001" } }, "distro-fedora": { "description": "Ubuntu icon", "default": { "fontPath": "./distroicons.woff", "fontCharacter": "\\E002" } } } } }contributes.iconThemes
Contribute a file icon theme to VS Code. File icons are shown next to file names, indicating the file type.
You must specify an id (used in the settings), a label and the path to the file icon definition file.
file icon theme example
{ "contributes": { "jsonValidation": [ { "fileMatch": ".jshintrc", "url": "https://json.schemastore.org/jshintrc" } ] } }contributes.keybindings
Contribute a key binding rule defining what command should be invoked when the user presses a key combination. See the Key Bindings topic where key bindings are explained in detail.
Contributing a key binding will cause the Default Keyboard Shortcuts to display your rule, and every UI representation of the command will now show the key binding you have added. And, of course, when the user presses the key combination the command will be invoked.
Note: Because VS Code runs on Windows, macOS and Linux, where modifiers differ, you can use "key" to set the default key combination and overwrite it with a specific platform.
Note: When a command is invoked (from a key binding or from the Command Palette), VS Code will emit an activationEvent onCommand:${command}.
keybinding example
Defining that Ctrl+F1 under Windows and Linux and Cmd+F1 under macOS trigger the "extension.sayHello" command:
{ "contributes": { "languages": [ { "id": "python", "extensions": [".py"], "aliases": ["Python", "py"], "filenames": [], "firstLine": "^#!/.*\\bpython[0-9.-]*\\b", "configuration": "./language-configuration.json", "icon": { "light": "./icons/python-light.png", "dark": "./icons/python-dark.png" } } ] } }contributes.menus
Contribute a menu item for a command to the editor or Explorer. The menu item definition contains the command that should be invoked when selected and the condition under which the item should show. The latter is defined with the when clause, which uses the key bindings when clause contexts.
A command property indicates which command to run when selecting a menu item. A submenu property indicates which submenu to render in this location.
When declaring a command menu item, an alternative command can also be defined using the alt-property. It will be shown and invoked when pressing Alt while opening a menu. On Windows and Linux Shift also does this, which is useful in situations where Alt would trigger the window menu bar.
Last, a group property defines sorting and grouping of menu items. The navigation group is special as it will always be sorted to the top/beginning of a menu.
Note that when clauses apply to menus and enablement clauses to commands. The enablement applies to all menus and even keybindings while the when only applies to a single menu.
Currently extension writers can contribute to:
- commandPalette - global Command Palette
- comments/comment/title - Comments title menu bar
- comments/comment/context - Comments context menu
- comments/commentThread/title - Comments thread title menu bar
- comments/commentThread/context- Comments thread context menu
- debug/callstack/context - Debug Call Stack view context menu
- debug/callstack/context group inline - Debug Call Stack view inline actions
- debug/toolBar - Debug view toolbar
- debug/variables/context - Debug Variables view context menu
- editor/context - editor context menu
- editor/lineNumber/context - editor line number context menu
- editor/title - editor title menu bar
- editor/title/context - editor title context menu
- editor/title/run - Run submenu on the editor title menu bar
- explorer/context - Explorer view context menu
- extension/context - Extensions view context menu
- file/newFile - New File item in the File menu and Welcome page
- interactive/toolbar - Interactive Window toolbar
- interactive/cell/title - Interactive Window cell title menu bar
- notebook/toolbar - notebook toolbar
- notebook/cell/title - notebook cell title menu bar
- notebook/cell/execute - notebook cell execution menu
- scm/title - SCM title menu
- scm/resourceGroup/context - SCM resource groups menus
- scm/resourceFolder/context - SCM resource folders menus
- scm/resourceState/context - SCM resources menus
- scm/change/title - SCM change title menus
- scm/repository - SCM repository menu
- scm/sourceControl- SCM source control menu
- terminal/context - terminal context menu
- terminal/title/context - terminal title context menu
- testing/item/context - Test Explorer item context menu
- testing/item/gutter - menu for a gutter decoration for a test item
- timeline/title - Timeline view title menu bar
- timeline/item/context - Timeline view item context menu
- touchBar - macOS Touch Bar
- view/title - View title menu
- view/item/context - View item context menu
- webview/context - any webview context menu
- Any contributed submenu
Note 1: When a command is invoked from a (context) menu, VS Code tries to infer the currently selected resource and passes that as a parameter when invoking the command. For instance, a menu item inside the Explorer is passed the URI of the selected resource and a menu item inside an editor is passed the URI of the document.
Note 2: Commands of menu items contributed to editor/lineNumber/context are also passed the line number. Additionally these items can reference the editorLineNumber context key in their when clauses, for example by using the in or not in operators to test it against an array-valued context key managed by the extension.
In addition to a title, a contributed command can specify the icon which VS Code will show when the invoking menu item is represented as a button, for example on a title menu bar.
menu example
Here's a command menu item:
{ "contributes": { "menus": { "view/title": [ { "command": "terminalApi.sendText", "when": "view == terminal", "group": "navigation" } ] } } }Here's a submenu menu item:
{ "commands": [ { "command": "extension.sayHello", "title": "Hello World" } ], "menus": { "commandPalette": [ { "command": "extension.sayHello", "when": "editorHasSelection" } ] } }Sorting of groups
Menu items can be sorted into groups. They are sorted in lexicographical order with the following defaults/rules. You can add menu items to these groups or add new groups of menu items in between, below, or above.
The editor context menu has these default groups:
- navigation - The navigation group comes first in all cases.
- 1_modification - This group comes next and contains commands that modify your code.
- 9_cutcopypaste - The second last default group with the basic editing commands.
- z_commands - The last default group with an entry to open the Command Palette.
The explorer context menu has these default groups:
- navigation - Commands related to navigation across VS Code. This group comes first in all cases.
- 2_workspace - Commands related to workspace manipulation.
- 3_compare - Commands related to comparing files in the diff editor.
- 4_search - Commands related to searching in the search view.
- 5_cutcopypaste - Commands related to cutting, copying, and pasting of files.
- 6_copypath - Commands related to copying file paths.
- 7_modification - Commands related to the modification of file.
The editor tab context menu has these default groups:
- 1_close - Commands related to closing editors.
- 3_preview - Commands related to pinning editors.
The editor title menu has these default groups:
- navigation - Commands related to navigating.
- 1_run - Commands related to running and debugging the editor.
- 1_diff - Commands related to working with diff editors.
- 3_open - Commands related to opening editors.
- 5_close - Commands related to closing editors.
navigation and 1_run are shown in the primary editor title area. The other groups are shown in the secondary area - under the ... menu.
The terminal tab context menu has these default groups:
- 1_create - Commands related to creating terminals.
- 3_run - Commands related to running/executing something in the terminal.
- 5_manage - Commands related to managing a terminal.
- 7_configure - Commands related to terminal configuration.
The terminal context menu has these default groups:
- 1_create - Commands related to creating terminals.
- 3_edit - Commands related to manipulating text, the selection or the clipboard.
- 5_clear - Commands related to clearing the terminal.
- 7_kill - Commands related to closing/killing the terminal.
- 9_config - Commands related to terminal configuration.
The Timeline view item context menu has these default groups:
- inline - Important or frequently used timeline item commands. Rendered as a toolbar.
- 1_actions - Commands related to working with timeline items.
- 5_copy - Commands related to copying timeline item information.
The Extensions view context menu has these default groups:
- 1_copy - Commands related to copying extension information.
- 2_configure - Commands related to configuring an extension.
Sorting inside groups
The order inside a group depends on the title or an order-attribute. The group-local order of a menu item is specified by appending @<number> to the group identifier as shown below:
{ "contributes": { "problemMatchers": [ { "name": "gcc", "owner": "cpp", "fileLocation": ["relative", "${workspaceFolder}"], "pattern": { "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", "file": 1, "line": 2, "column": 3, "severity": 4, "message": 5 } } ] } }This problem matcher can now be used in a tasks.json file via a name reference $gcc. An example looks like this:
{ "contributes": { "productIconThemes": [ { "id": "elegant", "label": "Elegant Icon Theme", "path": "./producticons/elegant-product-icon-theme.json" } ] } }See the Product Icon Theme Guide on how to create a Product Icon Theme.
contributes.resourceLabelFormatters
Contributes resource label formatters that specify how to display URIs everywhere in the workbench. For example here's how an extension could contribute a formatter for URIs with scheme remotehub:
{ "contributes": { "semanticTokenModifiers": [ { "id": "native", "description": "Annotates a symbol that is implemented natively" } ] } }See the Semantic Highlighting Guide to read more about semantic highlighting.
contributes.semanticTokenScopes
Contributes mapping between semantic token types & modifiers and scopes either as a fallback or to support language-specific themes.
{ "contributes": { "semanticTokenTypes": [ { "id": "templateType", "superType": "type", "description": "A template type." } ] } }See the Semantic Highlighting Guide to read more about semantic highlighting.
contributes.snippets
Contribute snippets for a specific language. The language attribute is the language identifier and the path is the relative path to the snippet file, which defines snippets in the VS Code snippet format.
The example below shows adding snippets for the Go language.
{ "contributes": { "submenus": [ { "id": "git.commit", "label": "Commit" } ] } }contributes.taskDefinitions
Contributes and defines an object literal structure that allows to uniquely identify a contributed task in the system. A task definition has at minimum a type property but it usually defines additional properties. For example a task definition for a task representing a script in a package.json file looks like this:
let task = new vscode.Task({ type: 'npm', script: 'test' }, ....);contributes.terminal
Contribute a terminal profile to VS Code, allowing extensions to handle the creation of the profiles. When defined, the profile should appear when creating the terminal profile
vscode.window.registerTerminalProfileProvider('my-ext.terminal-profile', { provideTerminalProfile( token: vscode.CancellationToken ): vscode.ProviderResult<vscode.TerminalOptions | vscode.ExtensionTerminalOptions> { return { name: 'Profile from extension', shellPath: 'bash' }; } });contributes.themes
Contribute a color theme to VS Code, defining workbench colors and styles for syntax tokens in the editor.
You must specify a label, whether the theme is a dark theme or a light theme (such that the rest of VS Code changes to match your theme) and the path to the file (JSON format).
theme example
{ "contributes": { "typescriptServerPlugins": [ { "name": "typescript-styled-plugin" } ] } }The above example extension contributes the typescript-styled-plugin which adds styled-component IntelliSense for JavaScript and TypeScript. This plugin will be loaded from the extension and must be installed as a normal NPM dependency in the extension:
{ "contributes": { "typescriptServerPlugins": [ { "name": "typescript-styled-plugin", "enableForWorkspaceTypeScriptVersions": true } ] } }Plugin configuration
Extensions can send configuration data to contributed TypeScript plugins through an API provided by VS Code's built-in TypeScript extension:
// In your TypeScript plugin import * as ts_module from 'typescript/lib/tsserverlibrary'; export = function init({ typescript }: { typescript: typeof ts_module }) { return { create(info: ts.server.PluginCreateInfo) { // Create new language service }, onConfigurationChanged(config: any) { // Receive configuration changes sent from VS Code } }; };This API allows VS Code extensions to synchronize VS Code settings with a TypeScript server plugin, or dynamically change the behavior of a plugin. Take a look at the TypeScript TSLint plugin and lit-html extensions to see how this API is used in practice.
contributes.views
Contribute a view to VS Code. You must specify an identifier and name for the view. You can contribute to following view containers:
- explorer: Explorer view container in the Activity Bar
- scm: Source Control Management (SCM) view container in the Activity Bar
- debug: Run and Debug view container in the Activity Bar
- test: Test view container in the Activity Bar
- Custom view containers contributed by Extensions.
When the user opens the view, VS Code will then emit an activationEvent onView:${viewId} (onView:nodeDependencies for the example below). You can also control the visibility of the view by providing the when context value. The icon specified will be used when the title cannot be shown (e.g. when the view is dragged to the Activity Bar). The contextualTitle is used when the view is moved out of its default view container and needs additional context.
{ "contributes": { "viewsContainers": { "activitybar": [ { "id": "package-explorer", "title": "Package Explorer", "icon": "resources/package-explorer.svg" } ] }, "views": { "package-explorer": [ { "id": "package-dependencies", "name": "Dependencies" }, { "id": "package-outline", "name": "Outline" } ] } } }Icon specifications
-
Size: Icons should be 24x24 and centered.
-
Color: Icons should use a single color.
-
Format: It is recommended that icons be in SVG, though any image file type is accepted.
-
States: All icons inherit the following state styles:
State Opacity Default 60% Hover 100% Active 100%
contributes.viewsWelcome
Contribute welcome content to Custom views. Welcome content only applies to empty tree views. A view is considered empty if the tree has no children and no TreeView.message. By convention, any command links that are on a line by themselves are displayed as a button. You can specify the view that the welcome content should apply to with the view property. Visibility of the welcome content can be controlled with the when context value. The text to be displayed as the welcome content is set with the contents property.
{ "contributes": { "walkthroughs": [ { "id": "sample", "title": "Sample", "description": "A sample walkthrough", "steps": [ { "id": "runcommand", "title": "Run Command", "description": "This step will run a command and check off once it has been run.\n[Run Command](command:getting-started-sample.runCommand)", "media": { "image": "media/image.png", "altText": "Empty image" }, "completionEvents": ["onCommand:getting-started-sample.runCommand"] }, { "id": "changesetting", "title": "Change Setting", "description": "This step will change a setting and check off when the setting has changed\n[Change Setting](command:getting-started-sample.changeSetting)", "media": { "markdown": "media/markdown.md" }, "completionEvents": ["onSettingChanged:getting-started-sample.sampleSetting"] } ] } ] } }Completion events
By default, if no completionEvents events are provided, the step will be checked off when any of it's buttons are clicked, or if the step has no buttons, when it is opened. If finer control is required, a list of completionEvents can be provided.
Available completion events include:
- onCommand:myCommand.id: Check off step when a command has been run.
- onSettingChanged:mySetting.id: Check off step once the given setting has been modified.
- onContext:contextKeyExpression: Check off step when a context key expression evaluates true.
- extensionInstalled:myExt.id: Check off step if the given extension is installed.
- onView:myView.id: Check off step once a given view becomes visible.
- onLink:https://...: Check off step once a given link has been opened via a Walkthrough.
Once a step has been checked off, it will remain checked off until the user explicitly unchecks the step or resets their progress (via the Getting Started: Reset Progress command).