I thought I had seen every way a dev environment can fight back, then I tried Publishing a VS Code Extension for a plain color theme. You would expect a modern registry to take one command, the way npm publish does. Instead I spent the time on Azure DevOps personal access tokens and a UI that kept timing out on me.
If you have spent hours tuning syntax highlighting, a race condition in a Microsoft login form is not the reward you were after. What follows is the workaround for each of the messy parts, in the order I hit them.
Preparing your manifest for publishing a VS Code extension
Your package.json has to be right before you touch a CLI tool. The gotcha that cost me the most time: scoped names such as @my-handle/theme do not work if you want to support Open VSX. Cursor and VSCodium pull from there, and neither accepts the scope syntax.
{
"name": "twilight-cosmos-theme",
"displayName": "Twilight Cosmos",
"description": "A dark theme for deep focus sessions",
"version": "1.0.0",
"publisher": "your-id",
"engines": {
"vscode": "^1.75.0"
},
"icon": "assets/icon.png",
"contributes": {
"themes": [
{
"label": "Twilight Cosmos",
"uiTheme": "vs-dark",
"path": "./themes/twilight-cosmos-color-theme.json"
}
]
},
"keywords": ["theme", "dark", "cosmos", "color-theme"]
}
The contributes key is the hook that tells the editor where your JSON lives. Leave it out and you have shipped a dead folder. For keyword ideas, I have written about how AI can assist with code quality and metadata generation, though it will happily hallucinate your version number if you let it.
The Azure DevOps part
The official vsce (Visual Studio Code Extensions) CLI wants a Personal Access Token (PAT) from Azure DevOps. Getting one is where the process stalls for most people. The backend hangs, or it drops you on a generic landing page with no token in sight.
When Azure keeps erroring out, clicking again will not help. Give account provisioning 24 hours to settle. If you cannot wait, there is a manual hack: package the extension locally and upload the file straight to the Visual Studio Marketplace.
# The standard approach
npx vsce login <publisher_id>
npx vsce publish
# The "it's broken" workaround
npx vsce package
vsce package writes a .vsix file that you drag into the Marketplace dashboard. The CLI login never enters the picture.
Open VSX and the Cursor crowd
The Microsoft Marketplace is not the whole audience. Plenty of developers have moved to editors like Cursor, and those editors pull from Open VSX. If you build your theme inside an AI-assisted editor, my notes on Safe Code Refactoring in Cursor cover how I keep that from going sideways.
Publishing there needs an Eclipse Foundation account, a linked GitHub repo and a signed agreement. After that you publish with the ovsx tool. Open VSX tokens do not expire every few months the way Microsoft’s do, so once it works it stays working.
Why your README screenshots do not load
You ship the extension and the screenshots come out broken in the marketplace listing. Neither registry resolves relative URLs in your README.md. Use absolute URLs pointing at your main GitHub branch instead.
<!-- This will break -->

<!-- Use this instead -->

If Publishing a VS Code Extension is eating your dev hours, hand it over. I have been wrestling with WordPress and developer tooling since the 4.x days.
Takeaway on extension deployment
Most of the work here is infrastructure, not code. Transient Azure errors, namespace claims on Open VSX and tokens that expire mid-release are the parts that will cost you time. Get the manifest right, point the image paths at raw GitHub URLs, then upload the .vsix.