Change:
<!-- Do Not Delete This! bugreporttemplate --<!-- Please read our Rules of Conduct: --<!-- Read our guide about submitting issues: --<!-- Search existing issues to avoid creating duplicates. --<!-- Test using the latest Insiders build to see if your issue has already been fixed: --<!-- Instead of creating your report here, use 'Report Issue' from the 'Help' menu in VS Code to pre-fill useful information. --<!-- Launch with to check. --Does this issue occur when all extensions are disabled?: N/A <!-- If you answered No above, use 'Help: Start Extension Bisect' from Command Palette to try to identify the cause. --<!-- Issues caused by an extension need to be reported directly to the extension publisher. The 'Help Report Issue' dialog can assist with this. --- VS Code Version: 1.63.2 OS Version: Web There seems to be a mismatch in details about how to run an extension in a specified extension host versus reality. In my situation I have an extension which I'd like to run in the following way: When run in VS Code Desktop or VS Code with remote, I'd like the extension to execute in the . When run in VS Code Web (Codespaces or .dev), I'd like the extension to execute in the . Looking at the information outlined here: I believe I need to describe this extension with to request it is run in the . The details for this extensionKind explicitly outlines: In the case of VS Code for the Web with Codespaces, where no local extension host is available, such an extension can not load, unless it is also* a web extension. It will then be loaded in the web extension host Which leads me to believe I can also describe this as a as outlined here: Which states: My extension has both a and a entry point, as this seems to be supported in the link above and I would expect the entrypoint to be used in the web extension host and the entrypoint anywhere else. When running the extension on the desktop (normally or using remote), this seems to work as expected, however the web flavours of VS Code fail to load the extension with the error: This extension is disabled because it is not supported in Visual Studio Code for the Web Before I delve into the (rather complicated) loading code, I'd like to understand the intent here and whether the expectation is that an extension can be setup to run in this way.
Further details on this. I tested the example project as . Although it has a entrypoint when running in codespaces, it executes in the extension host using the entrypoint.
The web worker extension host has more limitations compared to the nodejs extension host. That's why we will mostly prefer to run an extension on the nodejs extension host if a nodejs extension host is available. In the case of , it doesn't have an , but it has a and a entry point. In code, we will as: when running on web when running on desktop This means: on VS Code Desktop, it will run in the (only) nodejs extension host on VS Code Desktop + a remote, it will run on the remote nodejs extension host on VS Code Web + a server (e.g. Codespace), it will run on the remote nodejs extension host on VS Code Web without a server (e.g. ), it will run on the web worker extension host. In case an extension would use and it would have both a and a entry point, we would to . This means: on VS Code Desktop, it will run in the (only) nodejs extension host on VS Code Desktop + a remote, it will run on the local nodejs extension host on VS Code Web + a server (e.g. Codespace), it will run on the web worker extension host on VS Code Web without a server (e.g. ), it will run on the web worker extension host. That being said, this is pretty complex and has a lot of corner cases, like for example if an extension , etc.
Thanks for the feedback on VS Code Desktop + a remote, it will run on the local nodejs extension host on VS Code Web + a server (e.g. Codespace), it will run on the web worker extension host on VS Code Web without a server (e.g. ), it will run on the web worker extension host. This is exactly what I want to happen and I'm glad this is the intent. However this setup yields the following error in Codespaces: I'll create a small extension to repro the issue...
Simple VSCode extension which replicates this issue: This extension has both and entrypoints as well as a . It fails to load in codespaces.
How do you load this extension? We might be running into one of those ugly corner cases where an extension needs to be published to the marketplace and installed such that it gets "installed" on the browser side. i.e. might be .
Erk. I upload it to the workspace and install it from there :/ How can I test this without publishing it?
How can we simulate a browser "installed" extension? i.e. I think it would need to be returned from here --
You can side load a browser installed extension using the command - and I also think knows and documented how to develop & test a web extension so that it can run on web worker extension host, for eg., it will be returned by line 1004. Can you please share the link to the doc?
Thanks, glad to see this is possible but currently trying to work out how to make it work. Using a target URI ( or unpacked) hits CORS violations and using a local URI path fails to locate the . Should this URI be fully qualified to the root of the running container or support variables?
Following these steps: I was able to prove the expected behaviour as working in Is there a way to test this in codespaces or can I assume it will just work the same and not use the other extension hosts?
With Codespaces, you mean the Codespaces Web UI? Out of the VS Code sources you can emulate this by running ! (more documentation is on the way)
IMO the extension should be able to run in the Web UI of a code server. Maybe the bug is here: Do we also need a alternative?
This is not a bug and it is working as designed. Above code is to show the state of the extension and it resonates with how extensions are enabled in different extension hosts. It seems this extension cannot run in any of our extension hosts because: this could be a pure browser extension and installed on the server In this case neither remote extension host nor web worker extension host can run this extension because former is missing main entry point and the latter does not find this extension. We do not generally run extensions across extension hosts - please correct me if I am wrong.
Thanks for the ongoing feedback. Yeah, starting a codespace and getting the extension to install and run in the web extensionHost. I'm confused, the example I shared mimics the setup outlined above by which should result in and therefore run as described above. The example has and entry points This would be a shame as the only workaround I have is to distribute multiple extensions which only differ in how is resolved (and have to manage how to ask a user to install the right one).
We've met today and agreed that this is a bug. However, it is very late to fix this for January. To align with the documentation at ! We agree: remove from the statement needs to be tweaked at
Thanks for persisting with this and glad there is agreement. I understand this fix is too late for the current release :) Let me know if I can help in any way.
I pushed the change in the .
Pushed changes in - In Web, an extension with browser endpoint is enabled when installed in remote. But I think does not support it completely. I still see extension is not loaded into web worker extension host. It seems the extension is not loaded here
To verify, please try out the following: download the vsix of vim from use the command open the web ui and see that the vim extension executes in the web worker extension host (check in Running Extensions). in the extension view, this extension is shown as installed in the remote, but the extension is still enabled.
I had to disable this again due to integration test failures. We'll try again via a PR.

Discussion:
// takes care of duplicates and picks a running location for each extension this._runningLocation = this._runningLocationClassifier.determineRunningLocation(localExtensions, remoteExtensions); <ins> // Some remote extensions could run locally in the web worker, so store them const remoteExtensionsThatNeedToRunLocally = filterByRunningLocation(remoteExtensions, this._runningLocation, ExtensionRunningLocation.LocalWebWorker); </ins> localExtensions = filterByRunningLocation(localExtensions, this._runningLocation, ExtensionRunningLocation.LocalWebWorker); remoteExtensions = filterByRunningLocation(remoteExtensions, this._runningLocation, ExtensionRunningLocation.Remote); <ins> // Add locally the remote extensions that need to run locally in the web worker for (const ext of remoteExtensionsThatNeedToRunLocally) { if (!includes(localExtensions, ext.identifier)) { localExtensions.push(ext); } } </ins> const result = this._registry.deltaExtensions(remoteExtensions.concat(localExtensions), []); if (result.removedDueToLooping.length > 0) { this._logOrShowMessage(Severity.Error, nls.localize('looping', "The following extensions contain dependency loops and have been disabled: {0}", result.removedDueToLooping.map(e => `'${e.identifier.value}'`).join(', ')));

return extensions.filter(ext => runningLocation.get(ExtensionIdentifier.toKey(ext.identifier)) === desiredRunningLocation); } <ins> function includes(extensions: IExtensionDescription[], identifier: ExtensionIdentifier): boolean { for (const extension of extensions) { if (ExtensionIdentifier.equals(extension.identifier, identifier)) { return true; } } return false; } </ins> registerSingleton(IExtensionService, ExtensionService);