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

vscode-react

v0.2.2

Published

Embed a browser-hosted VS Code workbench in React and bridge it to a host page over quickbus.

Readme

vscode-react

vscode-react embeds a browser-hosted VS Code workbench inside a React application and bridges it to the host page with quickbus.

It expects the embedded VS Code host to include the file-bus extension so file-system requests can be served by the outer page. You can build and host that companion VS Code instance with vscode-static-web.

Installation

npm install vscode-react

This package exports:

  • useVSCode
  • createDebugAdapterHost

Usage

import React from 'react';
import { createDebugAdapterHost, useVSCode } from 'vscode-react';

function App() {
  const fsHandlers = {
    readdir(path) {
      return ['demo.php'];
    },
    async readFile(path) {
      return Array.from(new TextEncoder().encode('<?php echo "Hello";'));
    },
    analyzePath(path) {
      if (path === '/' || path === '/workspace') {
        return { exists: true, object: { isFolder: true } };
      }

      if (path === '/workspace/demo.php') {
        return { exists: true, object: { isFolder: false } };
      }

      return { exists: false, object: { isFolder: false } };
    }
  };

  const debugHost = createDebugAdapterHost({
    commands: {
      async initialize({ sendEvent }) {
        await sendEvent('initialized');
        return {
          supportsConfigurationDoneRequest: true
        };
      },
      launch() {
        return {};
      },
      setBreakpoints({ arguments: args }) {
        return {
          breakpoints: (args?.breakpoints ?? []).map(breakpoint => ({
            verified: true,
            line: breakpoint.line
          }))
        };
      },
      async configurationDone({ sendEvent }) {
        await sendEvent('stopped', {
          reason: 'entry',
          threadId: 1,
          allThreadsStopped: true
        });

        return {};
      },
      threads() {
        return {
          threads: [{ id: 1, name: 'Main Thread' }]
        };
      },
      stackTrace() {
        return {
          stackFrames: [{
            id: 1,
            name: 'main',
            line: 1,
            column: 1,
            source: {
              name: 'demo.php',
              path: '/workspace/demo.php'
            }
          }],
          totalFrames: 1
        };
      },
      scopes() {
        return {
          scopes: [{
            name: 'Locals',
            variablesReference: 0,
            expensive: false
          }]
        };
      },
      continue() {
        return {
          allThreadsContinued: true
        };
      },
      async disconnect({ sendEvent }) {
        await sendEvent('terminated');
        return {};
      }
    }
  });

  const { VSCode, ready, openFile, startDebugging, sendDebugAdapterMessage } = useVSCode({
    url: 'https://your-vscode-host.example/editor/',
    fsHandlers,
    dbgHandlers: debugHost.dbgHandlers,
  });

  debugHost.attachBridge({ sendDebugAdapterMessage });

  async function runDebugger() {
    await ready;
    await openFile('/workspace/demo.php');
    await startDebugging({
      type: 'dbgBus',
      request: 'launch',
      name: 'PHP DBG Wasm',
      program: '/workspace/demo.php'
    });
  }

  return <VSCode className="editor" />;
}

export default App;

The url should point at a VS Code web host that includes file-bus. If you want debugger support as well, that host also needs dbg-bus. The iframe host must post a ready message shaped like { kind: 'vscode-react', type: 'ready' } to the parent window once its command bridge is usable. If you control the host with vscode-web-static, that handshake is emitted automatically by the shared bootstrap after window.vscodeEditorReady resolves. ready is intentionally a one-shot "first usable boot" promise; the bridge methods below will automatically wait for a later iframe reload to become ready again.

Hook API

useVSCode(options)

| Option | Type | Description | | ---------------- | ------ | ------------------------------------------------------------- | | url | string | Base URL of the VSCode editor server. | | fsHandlers | object | Custom file-system handler callbacks. | | dbgHandlers | object | Optional host-side debugger bridge callbacks. | | readyTimeoutMs | number | Optional timeout for the iframe ready handshake. Default 0 (disabled). |

Returned values

| Return | Type | Description | | ------------------------- | ------------------------------------------- | ----------------------------------------------------- | | VSCode | React component | The iframe-based VSCode component to render. | | ready | Promise<object> | Resolves when the iframe host first signals bridge readiness. | | openFile | (path: string, options?: object) => Promise<any> | Opens the given file in the VSCode editor. | | configure | (options?: object) => Promise<any> | Configures file-bus host options such as file associations. | | executeCommand | (command: string, ...args: any[]) => Promise<any> | Executes a VS Code command in the editor. | | startDebugging | (configuration: object, options?: object) => Promise<any> | Starts a dbgBus debug session. | | stopDebugging | (sessionId?: string) => Promise<any> | Stops a dbgBus debug session. | | sendDebugAdapterMessage | (sessionId: string, message: object) => Promise<any> | Sends one DAP message into the debug session. | | customRequest | (sessionId: string, command: string, args?: any) => Promise<any> | Sends a custom debug request. | | listDebugSessions | () => Promise<any> | Lists active debug sessions known to dbg-bus. | | listBreakpoints | () => Promise<any> | Lists all VS Code breakpoints. | | listOpenBreakpoints | () => Promise<any> | Lists breakpoints for open editors. | | addBreakpoint | (uri: string, line: number, column?: number) => Promise<any> | Adds a source breakpoint through dbg-bus. |

createDebugAdapterHost(options)

Creates a small host-side DAP wrapper for dbg-bus. It tracks sessions, wraps request handlers into valid DAP responses, and can emit DAP events back into VS Code through sendDebugAdapterMessage(...).

| Option | Type | Description | | ----------------- | ------ | ------------------------------------------------------------------ | | commands | object | Map of DAP request names such as initialize or stackTrace. | | onSessionEvent | function | Optional lifecycle callback for dbg-bus session notifications. |

Returned values

| Return | Type | Description | | ------------------- | -------- | ----------------------------------------------------------------- | | dbgHandlers | object | Host callbacks to pass into useVSCode({ dbgHandlers }). | | attachBridge | function | Binds the helper to a sendDebugAdapterMessage function. | | getSession | function | Returns one tracked debug session by id or the active session. | | getActiveSession | function | Returns the active debug session or null. | | listSessions | function | Returns a snapshot array of tracked debug sessions. | | sendEvent | function | Sends one DAP event into an active debug session. | | sendRequest | function | Sends one DAP request into an active debug session. |

Available VS Code commands

executeCommand proxies to the VS Code command registry. You can call any built-in or extension command by its identifier. For example:

  • workbench.action.files.newUntitledFile
  • workbench.action.openFolder
  • workbench.action.quickOpen
  • workbench.action.findInFiles
  • editor.action.gotoLine
  • editor.action.rename

See the full list of VS Code commands.

File System Handlers

The fsHandlers option lets you override the file-system callbacks. This API mirrors the file-bus host-page contract, which is loosely modeled on filesystem-style operations. By default, this hook uses the following stub handlers:

const defaultFsHandlers = {
  readdir(path: string, opts?: object): string[],
  async readFile(path: string, opts?: object): number[],
  analyzePath(path: string): { exists: boolean, object?: { isFolder?: boolean } },
  writeFile(path: string, data: number[]): void,
  rename(oldPath: string, newPath: string): void,
  mkdir(path: string, opts?: { recursive?: boolean }): void,
  unlink(path: string): void,
  rmdir(path: string): void,
  activate(): void
};

Handler signatures

| Handler | Signature | Description | | ------------ | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | | readdir | (path: string, opts?: object) => string[] | Reads a directory and returns an array of entry names. | | readFile | (path: string, opts?: object) => Promise<number[]> | Reads a file and returns content as an array of bytes (number[]). | | analyzePath| (path: string) => { exists: boolean, object?: { isFolder?: boolean } } | Checks if the path exists and whether file-bus should treat it as a folder. | | writeFile | (path: string, data: number[]) => void | Writes raw bytes to a file (data should be an array of numbers representing bytes). | | rename | (oldPath: string, newPath: string) => void | Renames or moves a file or directory. | | mkdir | (path: string, opts?: { recursive?: boolean }) => void | Creates a directory. Use opts.recursive to create nested directories if needed. | | unlink | (path: string) => void | Removes a file. | | rmdir | (path: string) => void | Removes a (empty) directory. | | activate | () => void | Called when the FS bridge is activated (e.g., after initial mount). |

Debug Handlers

The dbgHandlers option lets the host page provide the runtime-facing half of the dbg-bus bridge. These handlers are optional until you actually start a dbgBus session.

If dbgHandlers.acceptVSCodeMessage(...) is omitted, vscode-react returns a generic DAP failure response so VS Code fails clearly instead of waiting forever for a missing host adapter.

Handler signatures

| Handler | Signature | Description | | --------------------------- | -------------------------------------------------------- | ------------------------------------------------------------------ | | acceptVSCodeMessage | (session: object, message: object) => Promise<object> \| object | Accepts one DAP request from VS Code and returns the adapter reply. | | debugSessionStarted | (session: object) => void | Called when the inline adapter is created for a new debug session. | | didStartDebugSession | (session: object) => void | Called when VS Code reports that the session has started. | | didTerminateDebugSession | (session: object) => void | Called when VS Code terminates the session. | | didChangeActiveDebugSession | (session: object \| null) => void | Called when the active debug session changes. |

Minimal DAP Flow

The smallest useful dbg-bus flow looks like this:

  1. VS Code sends initialize.
  2. Your host responds with capabilities and emits initialized.
  3. VS Code sends launch or attach.
  4. VS Code sends setBreakpoints.
  5. VS Code sends configurationDone.
  6. Your host emits stopped when the runtime reaches a pause point.
  7. VS Code asks for threads, stackTrace, and scopes.
  8. VS Code sends stepping or resume requests such as continue.
  9. Your host emits terminated when the session exits.

The createDebugAdapterHost(...) helper is designed around that flow. A basic command map normally covers:

  • initialize
  • launch or attach
  • setBreakpoints
  • configurationDone
  • threads
  • stackTrace
  • scopes
  • continue
  • disconnect

The unit tests in tests/createDebugAdapterHost.test.mjs exercise that exact sequence with a minimal single-thread session.

Tests

npm test
npm run test:e2e

The browser E2E test bundles a small React harness, serves it alongside a local vscode-web-static build, and verifies that a real embedded VS Code workbench can:

  • boot successfully
  • request file data over file-bus
  • open a file through openFile(...)
  • accept executeCommand(...)
  • add a breakpoint through dbg-bus
  • start and stop a real dbgBus debug session end to end
  • exchange DAP events between the host page and the embedded debugger session

By default it uses the companion repo at /projects/vscode-web-static. You can override that with:

VSCODE_REACT_COMPANION_DIR=/path/to/vscode-web-static npm run test:e2e

Building

This package uses Babel to compile JSX and modern JavaScript for distribution.

npm run build

The compiled files will be placed in dist/.

License

Apache-2.0