Overview
The vscode.extensions namespace provides access to information about installed extensions and allows extensions to interact with each other.
all
Get all installed extensions.
const all: readonly Extension<any>[]
Example:
import * as vscode from 'vscode';
const allExtensions = vscode.extensions.all;
console.log(`Total extensions: ${allExtensions.length}`);
allExtensions.forEach(ext => {
console.log(`${ext.id} - ${ext.packageJSON.displayName}`);
});
getExtension
Get a specific extension by ID.
function getExtension(
extensionId: string
): Extension<any> | undefined
function getExtension<T>(
extensionId: string
): Extension<T> | undefined
The extension ID in the format publisher.name
Example:
const gitExtension = vscode.extensions.getExtension('vscode.git');
if (gitExtension) {
console.log(`Git extension version: ${gitExtension.packageJSON.version}`);
}
// With type parameter
interface GitAPI {
getRepositories(): Repository[];
}
const typedGitExt = vscode.extensions.getExtension<GitAPI>('vscode.git');
if (typedGitExt?.isActive) {
const api = typedGitExt.exports;
const repos = api.getRepositories();
}
Extension Object
The Extension<T> interface provides information about an extension:
interface Extension<T> {
// Extension identifier (publisher.name)
readonly id: string;
// Absolute path to extension directory
readonly extensionUri: Uri;
readonly extensionPath: string;
// Is extension active?
readonly isActive: boolean;
// Extension's package.json
readonly packageJSON: any;
// Extension kind (UI or Workspace)
readonly extensionKind: ExtensionKind;
// Exported API (if any)
readonly exports: T;
// Activate the extension
activate(): Thenable<T>;
}
Extension Communication
Extensions can export APIs for other extensions to use.
Exporting an API
In your extension:
// Define your API interface
export interface MyExtensionAPI {
getData(): Promise<string[]>;
performAction(data: any): void;
}
// Implement the API
class MyExtensionAPIImpl implements MyExtensionAPI {
async getData(): Promise<string[]> {
return ['data1', 'data2', 'data3'];
}
performAction(data: any): void {
console.log('Action performed:', data);
}
}
// Export the API from activate function
export function activate(context: vscode.ExtensionContext): MyExtensionAPI {
const api = new MyExtensionAPIImpl();
// Your extension setup...
return api; // This becomes the extension's exports
}
Consuming an API
In another extension:
import * as vscode from 'vscode';
interface MyExtensionAPI {
getData(): Promise<string[]>;
performAction(data: any): void;
}
const ext = vscode.extensions.getExtension<MyExtensionAPI>(
'publisher.my-extension'
);
if (ext) {
if (!ext.isActive) {
await ext.activate();
}
const api = ext.exports;
const data = await api.getData();
api.performAction({ type: 'test' });
}
Extension Events
onDidChange
Event fired when extensions are installed, uninstalled, enabled, or disabled.
const onDidChange: Event<void>
Example:
vscode.extensions.onDidChange(() => {
console.log('Extensions changed');
// Check for required extension
const required = vscode.extensions.getExtension('required.extension');
if (!required) {
vscode.window.showWarningMessage(
'Required extension is not installed'
);
}
});
Extension Kinds
Extensions can run in different environments:
enum ExtensionKind {
// Runs on the UI side (local machine)
UI = 1,
// Runs in the workspace (remote or local)
Workspace = 2
}
Example:
const ext = vscode.extensions.getExtension('some.extension');
if (ext) {
if (ext.extensionKind === vscode.ExtensionKind.UI) {
console.log('This extension runs in the UI');
} else if (ext.extensionKind === vscode.ExtensionKind.Workspace) {
console.log('This extension runs in the workspace');
}
}
Common Use Cases
Check for Extension Dependencies
export function activate(context: vscode.ExtensionContext) {
const pythonExt = vscode.extensions.getExtension('ms-python.python');
if (!pythonExt) {
vscode.window.showErrorMessage(
'This extension requires the Python extension',
'Install'
).then(selection => {
if (selection === 'Install') {
vscode.commands.executeCommand(
'workbench.extensions.installExtension',
'ms-python.python'
);
}
});
return;
}
// Rest of activation...
}
Wait for Extension to Activate
async function getGitAPI() {
const gitExtension = vscode.extensions.getExtension('vscode.git');
if (!gitExtension) {
throw new Error('Git extension not found');
}
if (!gitExtension.isActive) {
await gitExtension.activate();
}
return gitExtension.exports;
}
List Extensions by Publisher
function getExtensionsByPublisher(publisher: string) {
return vscode.extensions.all.filter(ext =>
ext.id.startsWith(`${publisher}.`)
);
}
const microsoftExts = getExtensionsByPublisher('ms-vscode');
console.log(`Microsoft extensions: ${microsoftExts.length}`);
Best Practices
Check Activation
Always check if an extension is active before accessing its exports
Version Your API
Include version information in your exported API for compatibility
Handle Missing Extensions
Gracefully handle cases where required extensions are not installed
Document Your API
Provide clear TypeScript types and documentation for your exported API
Real-World Example
Here’s a complete example of two extensions communicating:
// publisher.data-provider extension
export interface DataAPI {
version: string;
getProjects(): Promise<Project[]>;
onProjectsChanged: vscode.Event<void>;
}
interface Project {
name: string;
path: string;
}
class DataProvider implements DataAPI {
version = '1.0.0';
private _onProjectsChanged = new vscode.EventEmitter<void>();
readonly onProjectsChanged = this._onProjectsChanged.event;
async getProjects(): Promise<Project[]> {
// Implementation
return [];
}
}
export function activate(context: vscode.ExtensionContext): DataAPI {
return new DataProvider();
}
// publisher.data-consumer extension
import * as vscode from 'vscode';
interface DataAPI {
version: string;
getProjects(): Promise<Project[]>;
onProjectsChanged: vscode.Event<void>;
}
export async function activate(context: vscode.ExtensionContext) {
const dataExt = vscode.extensions.getExtension<DataAPI>(
'publisher.data-provider'
);
if (!dataExt) {
vscode.window.showErrorMessage('Data Provider extension is required');
return;
}
const api = dataExt.isActive ? dataExt.exports : await dataExt.activate();
console.log(`Using Data API version ${api.version}`);
// Listen to changes
context.subscriptions.push(
api.onProjectsChanged(async () => {
const projects = await api.getProjects();
console.log(`Projects updated: ${projects.length}`);
})
);
// Get initial data
const projects = await api.getProjects();
console.log(`Loaded ${projects.length} projects`);
}
Extension Anatomy
Learn about extension structure and lifecycle
Publishing
Publish your extension to the marketplace