A Python CLI for selecting and downloading a specific VS Code extension package (.vsix) from the Visual Studio Marketplace.
I built it after needing a repeatable way to prepare extensions for air-gapped VMs. The tool runs on a connected machine, identifies a package compatible with the target VS Code version and platform, and downloads it for transfer to the isolated VM.
Status: active development. The current CLI supports interactive use and automation, with tests covering version compatibility, platform selection, archive validation and JSON output.
VS Code's built-in extension UI requires marketplace access. On offline VMs you often still need specific plugins (language support, linters, themes, etc.) matching the exact VS Code version installed on that machine.
This tool lets you:
- Query the Marketplace API from a machine with internet
- Compare extension versions with your target VS Code version
- Choose from the platform packages actually published for that release
- Download the
.vsixand transfer it to the offline VM - Install locally via Extensions → … → Install from VSIX…
- Interactive menus with pagination for extensions with many versions
- VS Code engine compatibility hints (
^1.85.0,>=1.70.0, etc.) - Platform-aware package selection with universal-package fallback
- Pre-release filtering (excluded by default)
- Non-interactive mode for scripting and batch downloads
- Machine-readable JSON output, including the checksum after a download
- Atomic downloads with SHA256 digest and VSIX archive validation
- Retries with backoff on transient HTTP errors
- Python 3.9+
- Network access to
marketplace.visualstudio.com(on the download host)
git clone https://github.com/alexandretorres17/vscode-vsix-picker.git
cd vscode-vsix-picker
python -m venv .venv
# Windows
.venv\Scripts\activate
# Linux / macOS
source .venv/bin/activate
pip install .This installs the vsix-picker command. It can also be run as a Python module:
vsix-picker ms-python.python --vscode 1.95.0
python -m vscode_vsix_picker ms-python.python --vscode 1.95.0vsix-picker ms-python.python --vscode 1.95.0Follow the prompts to pick a version and platform. The tool prints the direct vspackage URL and optionally downloads the file.
vsix-picker ms-python.python \
--vscode 1.95.0 \
--version 2024.20.0 \
--platform win32-x64 \
--download \
--out python.vsixWhen stdin is not a TTY, you must provide all options explicitly:
vsix-picker ms-python.python \
--vscode 1.95.0 \
--version 2024.20.0 \
--platform linux-x64 \
--download < /dev/nullUse universal for platform-agnostic packages (no targetPlatform query parameter).
vsix-picker ms-python.python \
--version 2024.20.0 \
--platform win32-x64 \
--jsonWhen combined with --download, the JSON document also contains downloadPath and sha256. Progress messages are written to standard error so standard output remains valid JSON.
vsix-picker ms-python.python --include-prerelease[Connected host] [Air-gapped VM]
| |
vsix-picker --download USB / shared folder
| |
extension.vsix -----------------> Install from VSIX
- On a machine with internet, run this tool and download the
.vsix - Copy the file to the VM (USB, internal share, etc.)
- In VS Code on the VM: open the Extensions view →
…menu → Install from VSIX… - Select the transferred file
Tip: pass --vscode with the exact version running on the VM to filter compatible extension releases.
| Label | targetPlatform value |
|---|---|
| Universal | (empty / universal) |
| Windows x64 | win32-x64 |
| Windows ARM64 | win32-arm64 |
| Linux x64 | linux-x64 |
| Linux ARM64 | linux-arm64 |
| Linux ARMv7 | linux-armhf |
| Alpine x64 | alpine-x64 |
| Alpine ARM64 | alpine-arm64 |
| macOS x64 | darwin-x64 |
| macOS ARM64 | darwin-arm64 |
| Web | web |
The tool calls the Visual Studio Marketplace extensionquery endpoint to list versions, engine constraints and the platform packages published for each release. It then builds the public vspackage download URL:
https://marketplace.visualstudio.com/_apis/public/gallery/publishers/
{publisher}/vsextensions/{extension}/{version}/vspackage
?targetPlatform={platform}
Semver matching uses the semantic-version library, with a built-in fallback for common range formats. A downloaded file is kept with a temporary .part suffix until the transfer completes and the result is confirmed to be a valid ZIP-based VSIX archive.
Install the package in editable mode and run the standard-library test suite:
pip install -e .
python -m unittest discover -s tests -vThe GitHub Actions workflow runs the same tests on Python 3.9, 3.12 and 3.13.
src/vscode_vsix_picker/
├── cli.py # Arguments, interactive menus and output
├── marketplace.py # Marketplace API, versions and platform selection
├── download.py # Atomic download, checksum and archive validation
└── __main__.py # python -m vscode_vsix_picker entry point
tests/
├── test_cli.py
├── test_marketplace.py
└── test_download.py
The package name is vscode_vsix_picker, while the user-facing command remains the shorter vsix-picker.
- Relies on the Marketplace API (not officially documented; may change)
- Engine compatibility checks are best-effort; always verify the extension on the target VM
- The tool downloads one package at a time and does not yet maintain an offline extension catalogue
The tool does not require credentials, store Marketplace data or send telemetry. It is a personal open-source project and is not affiliated with Microsoft or Visual Studio Code.
MIT — see LICENSE.