npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@gitbybit/vscode-extension-test-vitest-runner

v0.0.8

Published

Vitest plugin for running VS Code extension tests inside the extension host.

Readme

THIS IS A PROTOTYPE. USE AT YOUR OWN RISK. NO SUPPORT SHOULD BE EXPECTED

VS Code Vitest Runner

Experimental Vitest plugin for running VS Code extension tests inside a real VS Code Extension Development Host.

Why This Exists

VS Code extension tests that import vscode need to execute inside the VS Code extension host. Normal Vitest workers run in regular Node processes, so import * as vscode from 'vscode' cannot be resolved there.

This package provides a Vitest plugin backed by a custom pool. The pool launches VS Code with @vscode/test-electron, connects the external Vitest process to a small bridge running inside the extension host, and runs the test files there.

Vitest CLI / IDE
  -> custom Vitest pool
     -> @vscode/test-electron
        -> VS Code Extension Development Host
           -> Vitest worker bridge
              -> test files import "vscode"

Usage

import { defineConfig } from 'vitest/config';
import { vscodeExtensionHost } from '@gitbybit/vscode-extension-test-vitest-runner';

export default defineConfig({
  plugins: [
    vscodeExtensionHost({
      extensionDevelopmentPath: 'path/to/extension'
    })
  ],
  test: {
    include: ['test/**/*.test.ts'],
    globals: true
  }
});

The plugin sets Vitest to a single in-process VS Code extension-host worker, resolves the virtual vscode module through an extension-host CommonJS shim, and points Vitest at the internal extension-host bridge.

The plugin resolves the VS Code test executable during Vitest's config startup via @vscode/test-electron, before the custom pool starts running test files. If the matching VS Code test build is not already cached, the first run downloads it into cachePath (.vscode-test by default); later runs reuse that cache. This keeps download time out of individual test timeouts while avoiding package-manager install hooks.

If VS Code is provisioned separately, pass its executable path to skip @vscode/test-electron downloads:

vscodeExtensionHost({
  extensionDevelopmentPath: 'path/to/extension',
  vscodeExecutablePath: '/path/to/Code'
});

As of May 22, 2026, this runner is developed against VS Code 1.121.0 test downloads through @vscode/test-electron 2.5.2, with vitest 4.1.7. In that VS Code extension-host runtime, the vscode module is not a package on disk. VS Code provides it as a virtual CommonJS module to extension code. The runner keeps test imports natural (import * as vscode from 'vscode') but maps that specifier to an internal shim that calls require('vscode') inside the extension host.

This avoids a subtle platform trap in Vitest 4.1.7's external-module path. The relevant source is VitestModuleEvaluator.convertIdToImportUrl() in packages/vitest/src/runtime/moduleRunner/moduleEvaluator.ts. On Windows, that method converts non-URL external ids to file:// URLs so native ESM can import real Windows paths. That conversion is correct for paths, but not for the virtual vscode module. If bare vscode is externalized, it can be treated like a path and Node will search for a real file/package instead of letting the extension host provide the API.

Useful options:

vscodeExtensionHost({
  extensionDevelopmentPath: 'path/to/extension',
  launchArgs: ['--disable-extensions'],
  startupTimeoutMs: 30_000
});

Debugging

Tests run inside the spawned VS Code extension host. IDE debuggers must attach to that extension host, not to the outer npm or Vitest process.

Do not use an IDE's normal Vitest debug action for breakpoints in these tests. That debugs the outer Vitest process; test code that imports vscode runs in the spawned extension host.

Debug Option

Leave debug unset for normal test runs.

Use debug when you need to attach a debugger to extension-host code:

vscodeExtensionHost({
  extensionDevelopmentPath: 'path/to/extension',
  debug: true
});

debug: true opens VS Code's extension-host inspector on 127.0.0.1:9229 and does not pause startup. It does not attach your IDE automatically; start the test run, then attach with an IDE debug configuration that targets that port, such as a VS Code extensionHost attach config or a JetBrains Node.js/Chrome attach config. Use this when the test can start immediately and you only need breakpoints that will be reached after the debugger attaches.

Choose an explicit port when 9229 is already in use, or when you want a stable IDE launch configuration:

vscodeExtensionHost({
  extensionDevelopmentPath: 'path/to/extension',
  debug: {
    port: 9230
  }
});

Use break: true when you need the extension host to wait for the debugger before code runs:

vscodeExtensionHost({
  extensionDevelopmentPath: 'path/to/extension',
  debug: {
    port: 9230,
    break: true
  },
  startupTimeoutMs: 300_000
});

break: true is useful for debugging module load, extension activation, bridge startup, and the first lines of a test file. Raise startupTimeoutMs because Vitest waits for the extension-host bridge to connect, and that bridge cannot connect while the extension host is paused at startup.

Repo Debug Script

This repo includes a manual debugging script:

pnpm run debug:extension-host -- <test-file>

It uses test/vitest.debug.config.ts, opens the extension-host inspector on 127.0.0.1:9230, sets break: true, and raises startupTimeoutMs to 5 minutes.

vscodeExtensionHost({
  extensionDevelopmentPath: 'test/sample-extension',
  debug: {
    port: 9230,
    break: true
  }
});

VS Code

This repo includes .vscode/launch.json with:

{
  "name": "Attach Vitest VS Code Extension Host",
  "type": "extensionHost",
  "request": "attach",
  "port": 9230,
  "sourceMaps": true
}

To debug a test:

  1. Set a breakpoint in test/suite/*.test.ts or test/sample-extension/src/extension.ts.

  2. Start the debuggable run:

    pnpm run debug:extension-host -- test/suite/vscode-api-pass.test.ts
  3. Wait for:

    Started local extension host with pid ...
  4. Run the Attach Vitest VS Code Extension Host debug configuration.

JetBrains IDEs

For PHPStorm, WebStorm, or IntelliJ IDEA, create this run configuration once:

Type: Attach to Node.js/Chrome
Host: 127.0.0.1
Port: 9230

To debug a test:

  1. Set a breakpoint in test/suite/*.test.ts or test/sample-extension/src/extension.ts.

  2. Start the debuggable run:

    pnpm run debug:extension-host -- test/suite/vscode-api-pass.test.ts
  3. Wait for:

    Started local extension host with pid ...
  4. Run the Attach to Node.js/Chrome configuration.

Only one extension-host debug run can use 127.0.0.1:9230 and the test VS Code profile at a time. Stop the current debug run before starting another one.

Repository Layout

src/
  plugin.ts                         public Vitest plugin/helper
  external-pool.ts                  custom Vitest pool that launches VS Code
  external-extension-host-runner.mts bridge loaded by VS Code
  framed-ipc.ts                     small framed TCP protocol

test/
  sample-extension/                 fixture VS Code extension
  suite/                            sample Vitest tests
  vitest.config.ts                  dogfood config using the plugin

Scripts

The repo keeps only public workflow scripts in package.json:

pnpm run build                    # build the plugin and sample extension
pnpm run typecheck                # typecheck all TypeScript projects
pnpm run debug:extension-host     # build, then start a debuggable extension-host run
pnpm run test:vitest              # build, then run the Vitest dogfood suite
pnpm run test:extension-host-debugger

pnpm run build clears dist/ and test/sample-extension/dist/, then compiles both the published runner and the fixture extension.

pnpm run typecheck checks the plugin, test harness, sample suite, and sample extension projects.

The sample suite intentionally contains one failing test so file-level and test-level reporting can be inspected in Vitest and IDE integrations.

pnpm run test:extension-host-debugger is not part of the manual debugging flow. It is an internal smoke check for this repo that verifies the extension-host inspector can stop at a breakpoint in test/suite/vscode-api-pass.test.ts.

Current Limits

  • Watch mode is not a target yet.
  • Test execution is forced to one worker because the VS Code extension host is the worker.
  • The extension host bridge currently uses a TCP connection to report back to the external Vitest process.