12 Manifest

package.json as manifest analogous to plugin.xml

In VSCode extensions, package.json serves as the central manifest and defines metadata, dependencies, and extension-specific configurations. Functionally, it corresponds to plugin.xml from Eclipse plugin development but differs by using JSON syntax and npm integration.

12.1 Structural comparison to Eclipse plugin.xml

While Eclipse plugins declare their configuration in XML-based manifests, VSCode uses the npm standard format package.json with extension-specific additions:

Eclipse plugin.xml (example):

<?xml version="1.0" encoding="UTF-8"?>
<plugin>
   <extension point="org.eclipse.ui.commands">
      <command id="com.example.hello" name="Hello Command"/>
   </extension>
   <extension point="org.eclipse.ui.handlers">
      <handler commandId="com.example.hello" class="HelloHandler"/>
   </extension>
</plugin>

VSCode package.json (equivalent):

{
  "contributes": {
    "commands": [{
      "command": "extension.hello",
      "title": "Hello Command"
    }]
  },
  "activationEvents": [
    "onCommand:extension.hello"
  ]
}

12.2 Standard npm fields

The package.json begins with standard npm metadata, also used for regular Node.js packages:

{
  "name": "my-extension",
  "displayName": "My Extension",
  "description": "Extension description",
  "version": "1.0.0",
  "publisher": "publisher-name",
  "author": {
    "name": "Author Name",
    "email": "author@example.com"
  },
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "https://github.com/user/repo"
  },
  "keywords": ["vscode", "extension"],
  "categories": ["Other"]
}

12.2.1 Extension-specific required fields

VSCode extends the npm schema with extension-specific fields:

12.3 Engine compatibility and versioning

The engines field defines VSCode compatibility:

{
  "engines": {
    "vscode": "^1.74.0"
  }
}

This declaration corresponds to the Required-Bundle directive in Eclipse manifests and ensures that the extension is only activated in compatible VSCode versions. The caret symbol (^) allows minor and patch updates, but blocks breaking changes.

12.4 Activation Events

Activation events define when VSCode loads the extension. They replace Eclipse’s Bundle-ActivationPolicy concept:

{
  "activationEvents": [
    "onCommand:extension.hello",
    "onLanguage:typescript",
    "workspaceContains:**/package.json",
    "onFileSystem:sftp",
    "onStartupFinished"
  ]
}

Common activation events:

12.5 Contributes section: Extension Points

The contributes section declares extension points and corresponds to the <extension> elements in Eclipse:

{
  "contributes": {
    "commands": [{
      "command": "extension.hello",
      "title": "Hello World",
      "category": "Sample"
    }],
    "menus": {
      "commandPalette": [{
        "command": "extension.hello",
        "when": "editorTextFocus"
      }]
    },
    "keybindings": [{
      "command": "extension.hello",
      "key": "ctrl+f1",
      "when": "editorTextFocus"
    }],
    "languages": [{
      "id": "log",
      "aliases": ["Log File", "log"],
      "extensions": [".log"]
    }],
    "grammars": [{
      "language": "log",
      "scopeName": "text.log",
      "path": "./syntaxes/log.tmLanguage.json"
    }]
  }
}

12.5.1 Important extension points

Commands: Declaration of executable commands

"commands": [{
  "command": "extension.commandId",
  "title": "Command Title",
  "category": "Category Name",
  "icon": "$(symbol-file)"
}]

Menus: Integration into VSCode menu structures

"menus": {
  "editor/context": [{
    "command": "extension.commandId",
    "when": "resourceExtname == .ts",
    "group": "navigation"
  }]
}

Configuration: Custom user settings

"configuration": {
  "title": "My Extension",
  "properties": {
    "myExtension.enabled": {
      "type": "boolean",
      "default": true,
      "description": "Enable the extension"
    }
  }
}

12.6 Dependencies and devDependencies

Dependency management follows npm conventions:

{
  "dependencies": {
    "axios": "^1.0.0",
    "lodash": "^4.17.21"
  },
  "devDependencies": {
    "@types/vscode": "^1.74.0",
    "@types/node": "16.x",
    "typescript": "^4.9.4",
    "@typescript-eslint/eslint-plugin": "^5.45.0",
    "@typescript-eslint/parser": "^5.45.0",
    "eslint": "^8.28.0"
  }
}

Critical dependencies:

12.7 Scripts section

The scripts section defines build and development workflows:

{
  "scripts": {
    "vscode:prepublish": "npm run compile",
    "compile": "tsc -p ./",
    "watch": "tsc -watch -p ./",
    "pretest": "npm run compile && npm run lint",
    "lint": "eslint src --ext ts",
    "test": "node ./out/test/runTest.js",
    "package": "vsce package",
    "publish": "vsce publish"
  }
}

Important scripts:

12.8 Comparison of manifest philosophies

Aspect Eclipse plugin.xml VSCode package.json
Format XML-based JSON-based
Schema OSGi-specific npm standard extended
Dependency Management Manifest headers npm-integrated
Extension Points XML attributes JSON objects
Lifecycle Bundle activator activate/deactivate functions
Versioning OSGi semantic versioning npm semantic versioning

12.9 Validation and schema

VSCode validates package.json against an extension schema. Development environments offer IntelliSense support via the schema:

{
  "$schema": "https://raw.githubusercontent.com/Microsoft/vscode/master/extensions/extension-manifest.schema.json"
}

12.10 Best practices

Namespace conventions: Extension IDs should use unique prefixes:

"commands": [{
  "command": "mycompany.myextension.action"
}]

Performance optimization: Use minimal activation events:

"activationEvents": [
  "onLanguage:typescript"
]

Complete metadata: Meaningful descriptions for marketplace visibility:

{
  "description": "Detailed extension description",
  "keywords": ["typescript", "intellisense", "productivity"],
  "categories": ["Programming Languages"]
}