Skip to main content

Overview

The vscode.extensions namespace provides access to information about installed extensions and allows extensions to interact with each other.

Extension Information

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
extensionId
string
required
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:
extension.ts
// 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:
Data Provider Extension
// 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();
}
Consumer Extension
// 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

Build docs developers (and LLMs) love