Skip to content

Instantly share code, notes, and snippets.

@wanglf
Last active May 4, 2025 10:50
Show Gist options
  • Save wanglf/7acc591890dc0d8ceff1e7ec9af32a55 to your computer and use it in GitHub Desktop.
Save wanglf/7acc591890dc0d8ceff1e7ec9af32a55 to your computer and use it in GitHub Desktop.
Download VS Code extensions as VSIX

How to use?

  • Copy content of vsix-bookmarklet, create a bookmark in your browser.
  • Navigate to the web page of the VS Code extension you want to install.
  • Click the bookmark you just created, then click the download button.
    download
  • After download finished, rename the file extension to *.vsix.
  • In VS Code, select Install from VSIX... in the extension context menu.
    vsc

How does it work?

http://stackoverflow.com/a/38866913/1032492

A VS Code extension's offline install package (VSIX) is available at:

https://${publisher}.gallery.vsassets.io/_apis/public/gallery/publisher/${publisher}/extension/${extension name}/${version}/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage

Take the syntax highlight extension for Vue.js as an example:

https://marketplace.visualstudio.com/items?itemName=liuji-jim.vue

  • The itemName query is a composition of publisher and extension name, separated with a dot.
  • The publisher is liuji-jim.
  • The extension name is vue.
  • The latest version number is in More Info section on the right side.
    more

So the package can be downloaded via this URL:

https://liuji-jim.gallery.vsassets.io/_apis/public/gallery/publisher/liuji-jim/extension/vue/0.1.3/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage

javascript:!function(){(function(){for(var%20e={version:%22%22,publisher:%22%22,identifier:%22%22,getDownloadUrl:function(){return[%22https://%22,this.identifier.split(%22.%22)[0],%22.gallery.vsassets.io/_apis/public/gallery/publisher/%22,this.identifier.split(%22.%22)[0],%22/extension/%22,this.identifier.split(%22.%22)[1],%22/%22,this.version,%22/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage%22].join(%22%22)},getFileName:function(){return[this.identifier,%22_%22,this.version,%22.vsix%22].join(%22%22)},getDownloadButton:function(){var%20e=document.createElement(%22a%22);return%20e.innerHTML=%22Download%20VSIX%22,e.href=%22javascript:void(0);%22,e.style.fontFamily=%22wf_segoe-ui,Helvetica%20Neue,Helvetica,Arial,Verdana%22,e.style.display=%22inline-block%22,e.style.padding=%222px%205px%22,e.style.background=%22darkgreen%22,e.style.color=%22white%22,e.style.fontWeight=%22bold%22,e.style.margin=%222px%205px%22,e.setAttribute(%22data-url%22,this.getDownloadUrl()),e.setAttribute(%22data-filename%22,this.getFileName()),e.onclick=function(e){e.target.onclick=null,e.target.innerHTML=%22Downloading%20VSIX...%22;var%20t=new%20XMLHttpRequest;console.log(e.target.getAttribute(%22data-url%22)),t.open(%22GET%22,e.target.getAttribute(%22data-url%22),!0),t.responseType=%22blob%22,t.onprogress=function(t){if(t.lengthComputable){var%20r=t.loaded/t.total*100;e.target.innerHTML=%22Downloading%20VSIX...%22+r.toString()+%22%25%22}},t.onload=function(t){if(200==this.status){var%20r=this.response,n=document.createElement(%22a%22);n.href=window.URL.createObjectURL(r),n.download=e.target.getAttribute(%22data-filename%22),n.click(),e.target.href=n.href,e.target.download=n.download,e.target.innerHTML=%22Download%20VSIX%22}else%20e.target.innerHTML=%22Error.%20Please%20reload%20the%20page%20amd%20try%20again.%22,alert(%22Error%20%22+this.status+%22%20error%20receiving%20the%20document.%22)},t.onerror=function(t){e.target.innerHTML=%22Error.%20Please%20reload%20the%20page%20amd%20try%20again.%22,alert(%22Error%20%22+t.target.status+%22%20occurred%20while%20receiving%20the%20document.%20%22)},t.send()},e}},t={Version:%22version%22,Publisher:%22publisher%22,%22Unique%20Identifier%22:%22identifier%22},r=document.querySelectorAll(%22.ux-table-metadata%20tr%22),n=0;n%3Cr.length;n++){var%20i=r[n],a=i.querySelectorAll(%22td%22);if(2==a.length){var%20o=a[0].innerText.replace(/^\s+|\s+$/g,%22%22),l=a[1].innerText.replace(/^\s+|\s+$/g,%22%22);t.hasOwnProperty(o)%26%26(e[t[o]]=l)}}document.querySelector(%22.vscode-moreinformation%22).parentElement.appendChild(e.getDownloadButton()).scrollIntoView(),e})()}();
@aisiklar
Copy link

hi @wanglf and @guillaumegarcia13

I really wonder how you found this. But the below updated version worked for me.
Thanks a lot.

I hope vscode just reverts to previous state or implements another solution to download vsix for offline use.
BR.

Seems the URL has changed to: https://marketplace.visualstudio.com/_apis/public/gallery/publishers/${publisher}/vsextensions/${extension}/${version}/vspackage

Assuming this, here is a (very) rough bookmarklet: javascript:(function()%7Bconst%20URL_VSIX_PATTERN%20%3D%20'https%3A%2F%2Fmarketplace.visualstudio.com%2F_apis%2Fpublic%2Fgallery%2Fpublishers%2F%24%7Bpublisher%7D%2Fvsextensions%2F%24%7Bextension%7D%2F%24%7Bversion%7D%2Fvspackage'%3B%0A%0Alet%20itemName%20%3D%20new%20URL(window.location.href).searchParams.get('itemName')%3B%0Alet%20%5Bpublisher%2C%20extension%5D%20%3D%20itemName.split('.')%3B%0Alet%20version%20%3D%20document.querySelector('%23versionHistoryTab%20tbody%20tr%20.version-history-container-column').textContent%3B%0A%0Alet%20url%20%3D%20URL_VSIX_PATTERN.replace('%24%7Bpublisher%7D'%2C%20publisher)%0A%09%09%09%09%09%09%20%20.replace('%24%7Bextension%7D'%2C%20extension)%0A%09%09%09%09%09%09%20%20.replace('%24%7Bversion%7D'%2C%20version)%3B%0A%0Awindow.open(url%2C%20'_blank')%3B%7D)()%3B

@Norlandz
Copy link

https://gist.github.com/wanglf/7acc591890dc0d8ceff1e7ec9af32a55?permalink_comment_id=5534061#gistcomment-5534061

I just made this one - instead of doing something weird, it grabs the data as easily as possible for you to copy and paste:

javascript:(function(){
  var url = window.location.href;
  var match = url.match(/itemName=([^&]+)/);
  if(!match){alert('Could not find extension name'); return;}
  var itemName = match[1];
  var parts = itemName.split('.');
  var publisher = parts[0];
  var extension = parts[1];
  var versionElem = document.querySelector('td[aria-labelledby="Version"]');
  if(!versionElem){alert('Could not find version'); return;}
  var version = versionElem.textContent.trim();
  var downloadUrl = 'https://marketplace.visualstudio.com/_apis/public/gallery/publishers/'+publisher+'/vsextensions/'+extension+'/'+version+'/vspackage';
  alert('Download URL:\n'+downloadUrl);
})();

Now you need to change to lower case version then it works.

(function(){
  const url = window.location.href;
  const match = url.match(/itemName=([^&]+)/);
  if(!match){alert('Could not find extension name'); return;}
  const itemName = match[1];
  const parts = itemName.split('.');
  const publisher = parts[0];
  const extension = parts[1];
  const versionElem = document.querySelector('td[aria-labelledby="version"]');
  if(!versionElem){alert('Could not find version'); return;}
  const version = versionElem.textContent.trim();
  const downloadUrl = 'https://marketplace.visualstudio.com/_apis/public/gallery/publishers/'+publisher+'/vsextensions/'+extension+'/'+version+'/vspackage';
  console.log(downloadUrl)
})()

@MrNaceja
Copy link

I have created a download agent with Flutterflow, just paste the marketplace link and click "Download" the most updated version will be downloaded.

image

https://vscode-vsix-downloader.flutterflow.app/

@SHJordan
Copy link

In this example i'm getting the latest https://marketplace.visualstudio.com/items?itemName=laravel.vscode-laravel so the id is just the itemName just change the name for the extension you need:

run it on pwsh

$extensionId = "laravel.vscode-laravel"
$publisher, $name = $extensionId -split '\.'
$downloadUrl = "https://$publisher.gallery.vsassets.io/_apis/public/gallery/publisher/$publisher/extension/$name/latest/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage"
Invoke-WebRequest -Uri $downloadUrl -OutFile "$name.vsix" -UseBasicParsing

@anasfanani
Copy link

In this example i'm getting the latest https://marketplace.visualstudio.com/items?itemName=laravel.vscode-laravel so the id is just the itemName just change the name for the extension you need:

run it on pwsh

$extensionId = "laravel.vscode-laravel"
$publisher, $name = $extensionId -split '\.'
$downloadUrl = "https://$publisher.gallery.vsassets.io/_apis/public/gallery/publisher/$publisher/extension/$name/latest/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage"
Invoke-WebRequest -Uri $downloadUrl -OutFile "$name.vsix" -UseBasicParsing

Thanks for great simple solution.

#!/bin/sh

extensionId="laravel.vscode-laravel"
publisher=$(echo "$extensionId" | cut -d '.' -f 1)
name=$(echo "$extensionId" | cut -d '.' -f 2)
downloadUrl="https://$publisher.gallery.vsassets.io/_apis/public/gallery/publisher/$publisher/extension/$name/latest/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage"
curl -L "$downloadUrl" -o "$name.vsix"
version=$(unzip -p "$name.vsix" extension.vsixmanifest | grep -oP '<Identity[^>]+Version="\K[^"]+')
mv "$name.vsix" "${extensionId}-${version}.vsix"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment