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

react-code-locator

v0.4.4

Published

A package that lets you right-click any element in your React app during development to jump directly to its source code location.

Readme

React Code Locator

A package that lets you right-click any element in your React app during development to jump directly to its source code location.

  • Zero dependencies: No Babel, no React DevTools, no browser extension — just one build plugin.
  • React 19 support: fiber._debugSource was removed in React 19. This package injects source metadata at build time, so it works regardless of the React version.
  • Universal: Supports Vite, Webpack, Rollup, esbuild, and Rspack.
  • Dev only: No impact on production builds.

Installation

npm i -D react-code-locator

Quick Start

Vite

vitePlugin handles both source transform and automatic client runtime injection.

// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { vitePlugin } from "react-code-locator";

export default defineConfig({
  plugins: [
    react(),
    vitePlugin(),
  ],
});

Next.js (Webpack)

// next.config.js
const { webpackPlugin } = require("react-code-locator");

module.exports = {
  webpack(config) {
    config.plugins.push(webpackPlugin());
    return config;
  },
};

Create React App

// config-overrides.js
const { webpackPlugin } = require("react-code-locator");

module.exports = {
  webpack(config) {
    config.plugins.push(webpackPlugin());
    return config;
  },
};

Rollup

// rollup.config.js
import { rollupPlugin } from "react-code-locator";

export default {
  plugins: [rollupPlugin()],
};

esbuild

import { esbuildPlugin } from "react-code-locator";

await esbuild.build({
  plugins: [esbuildPlugin()],
});

Rspack

// rspack.config.js
const { rspackPlugin } = require("react-code-locator");

module.exports = {
  plugins: [rspackPlugin()],
};

Options

// Options shared by all plugins
webpackPlugin({
  // Whether to enable the plugin (default: NODE_ENV === "development")
  // Set this explicitly if you use a custom environment variable instead of NODE_ENV.
  enabled: process.env.MY_ENV === "dev",

  projectRoot: process.cwd(),    // Project root — base path for resolving source locations (default: process.cwd())
});

// Vite-only additional options
vitePlugin({
  enabled: process.env.MY_ENV === "dev",
  projectRoot: process.cwd(),

  // injectClient: true (default) — automatically injects enableReactComponentJump() into the HTML.
  // injectClient: false — disables auto injection; call enableReactComponentJump() manually.
  injectClient: true,

  editor: "code",                // Editor command (default: EDITOR env var → auto-detect running editor)

  locator: {                     // Runtime options (injected automatically when injectClient: true)
    triggerKey: "shift",         // Trigger key: "alt" | "meta" | "ctrl" | "shift" | "none" (default: "shift")
    projectRoot: process.cwd(),  // Base path for normalizing source paths (default: not set)
    openInEditor: true,          // Show "Open in editor" in the right-click menu (default: false)
    onLocate(result) {},         // Callback when a source location is found
    onError(error) {},           // Callback on error
  },
});

Usage

Hover Highlight

Hold the trigger key (default: Shift) and hover over an element. The element will be highlighted in blue like a DevTools inspector, showing the component file name and line number.

Right-Click Context Menu

Hold the trigger key and right-click an element to open the context menu.

| Item | Action | |------|--------| | Open in editor | Opens the source file in your editor (shown when openInEditor: true) | | Copy path | Copies the source path to the clipboard |

Keyboard Shortcuts

| Key | Action | |-----|--------| | Shift + Click | Print source location to the console | | Alt + 1 | Screen mode (components visible on screen, default) | | Alt + 2 | Implementation mode (implementation location) |

Opening in Editor

Set openInEditor: true to show the "Open in editor" option in the right-click menu.

Vite

// vite.config.ts
vitePlugin({
  editor: "code",   // VS Code CLI command
  locator: {
    openInEditor: true,
  },
})

Webpack / Rspack

You need to add openInEditorMiddleware to your devServer.

// webpack.config.js
const { webpackPlugin, openInEditorMiddleware } = require("react-code-locator");

module.exports = {
  plugins: [webpackPlugin()],
  devServer: {
    setupMiddlewares(middlewares) {
      middlewares.unshift({
        name: "open-in-editor",
        path: "/__open-in-editor",
        middleware: openInEditorMiddleware(),
      });
      return middlewares;
    },
  },
};
// main.tsx
import { enableReactComponentJump } from "react-code-locator";

enableReactComponentJump({ openInEditor: true });

The editor is determined by the EDITOR environment variable. If not set, the currently running editor is auto-detected.

EDITOR=code npm run dev       # VS Code
EDITOR=webstorm npm run dev
EDITOR=cursor npm run dev

Manual Setup

Disable auto injection with injectClient: false and call enableReactComponentJump manually to control activation. This approach is also used in non-Vite environments.

// vite.config.ts
vitePlugin({ injectClient: false })
// main.tsx
import { enableReactComponentJump } from "react-code-locator";

enableReactComponentJump({
  enabled: true,                   // default: true. Set to false to disable.
  triggerKey: "shift",             // "alt" | "meta" | "ctrl" | "shift" | "none" (default: "shift")
  projectRoot: "/path/to/project", // Base path for normalizing source paths (optional)
  openInEditor: true,              // Show "Open in editor" in the right-click menu
  onLocate(result) {
    console.log("Source:", result.source);  // result.source, result.mode
  },
  onError(error) {
    console.error("Error:", error);
  },
});

Known Limitations

  • React Native not supported: Relies on the DOM API.
  • Turbopack not supported: Turbopack in Next.js 13+ is not currently supported.
  • TSX generic arrow functions: Files containing generic arrow functions in the form <T,> in .tsx files will be skipped during transform. (function declarations and .ts files work fine.)
  • Disabled elements / blocked pointer-events: Elements with a disabled attribute or pointer-events: none applied will not fire click events and cannot be detected.
  • CRA (Create React App): The webpack config is hidden, so plugin injection requires react-app-rewired or craco.
  • Dev only: The plugin's enabled option defaults to NODE_ENV === "development", so it is automatically disabled in production builds.

License

MIT