Hyperse Inspector
@hyperse/inspector is the tool for seamlessly navigating from your browser to your IDE. With just a simple click, you can jump from a React component in the browser to its source code in your local IDE instantly. Think of it as a supercharged version of Chrome's Inspector, tailored for developers.
Table of Contents
- Why @hyperse/inspector?
- Features
- Installation
- How to Use and Configure
- Customization
- How It Works
- Supported IDEs/Editors
- Troubleshooting
- License
- Related Projects
Why @hyperse/inspector?
Have you ever run into any of these issues 🤔:
- You need to fix bugs in a team project, but you're lost trying to find where the page/component's code is located.
- You're excited to explore an open-source project, but struggle to pinpoint the implementation of a specific page or component.
- You're thinking about a component and want a quick peek at its code, without memorizing or manually navigating through deeply nested file paths.
That's exactly why @hyperse/inspector was created – to make your development workflow smoother and more efficient!
Features
- ✨ Instant Code Navigation: Click on a UI element in the browser and jump directly to its source code in your IDE.
- 🔌 IDE Integration: Launches your configured IDE/Editor pointing to the exact file and line number.
- 🛠️ Multi-framework Support: Works with popular bundlers and frameworks like Vite, Webpack, Rspack, and more.
- 🚀 Native SWC Plugin: Includes a high-performance SWC plugin for projects using SWC.
- ⚛️ React 19 Ready: Compatible with the latest React versions, including React 19.
- ⌨️ Customizable Hotkeys: Change the activation hotkey to fit your preferences.
- 🌍 Universal: Designed to work with various project setups.
Swc version
Due to the version incompatibility issue of swc, it is recommended that developers use the @hyperse/inspector:"~x.x.x" version to depend on the inspector package.
Starting from version 2.0, there will be incompatibilities in the minor versions. The fundamental reason for this is due to the swc_core version. The specific corresponding relationship can be viewed at selecting-swc-core.
Usage rspack
- rspack >= 1.6.0, use 2.x
- rspack < 1.6.0, use 1.x
Usage nextjs
Since the version of swc_core that turbopack relies on has not been upgraded yet, please use the 1.x version first.
Default Hotkeys
- macOS:
⌘ + i - Windows/Linux:
Ctrl + i
You can customize the hotkeys by passing the keys prop to the <Inspector/> component.
Installation
Choose your preferred package manager:
# npm npm install --save-dev @hyperse/inspector @hyperse/inspector-middleware @hyperse/inspector-babel-plugin # or @hyperse/inspector-swc-plugin # For Next.js projects, also install: npm install --save-dev @hyperse/next-inspector # yarn yarn add --dev @hyperse/inspector @hyperse/inspector-middleware @hyperse/inspector-babel-plugin # or @hyperse/inspector-swc-plugin # For Next.js projects, also install: yarn add --dev @hyperse/next-inspector # pnpm pnpm add --save-dev @hyperse/inspector @hyperse/inspector-middleware @hyperse/inspector-babel-plugin # or @hyperse/inspector-swc-plugin # For Next.js projects, also install: pnpm add --save-dev @hyperse/next-inspector
How to Use and Configure
Setting up @hyperse/inspector involves a few steps:
Step 1: Install Packages
(Covered in the Installation section above.) Make sure you install:
@hyperse/inspector: The core React component.@hyperse/inspector-middleware: The dev server middleware.- Either
@hyperse/inspector-babel-plugin(for Babel users) or@hyperse/inspector-swc-plugin(for SWC users). - For Next.js projects, also install:
@hyperse/next-inspector: The Next.js plugin
Step 2: Add the Inspector Component to Your App
Import and render the <Inspector /> component in your application's root or main layout component. It's a good practice to only include it during development.
// src/App.tsx or your main layout component import { Inspector } from '@hyperse/inspector'; import { useState } from 'react'; // Optional: for controlled mode export default function App() { // Optional: for controlled mode const [inspectorActive, setInspectorActive] = useState(false); // Conditionally render the Inspector only in development const isDevelopment = process.env.NODE_ENV === 'development'; return ( <div> {isDevelopment && ( <Inspector // Optional: Customize hotkeys // keys={['Control', 'Shift', 'i']} // Optional: Controlled mode // active={inspectorActive} // onActiveChange={setInspectorActive} /> )} {/* Your other application components */} </div> ); }
Step 3: Configure the Build Tool Plugin (Babel or SWC)
This plugin injects necessary source location information into your JSX elements during the build process.
For Babel Users (@hyperse/inspector-babel-plugin)
Add @hyperse/inspector-babel-plugin to your Babel configuration (e.g., babel.config.js or .babelrc.js).
// babel.config.js module.exports = { presets: [ '@babel/preset-env', '@babel/preset-typescript', ['@babel/preset-react', { runtime: 'automatic' }], ], plugins: [ // Add the inspector plugin only in development mode process.env.NODE_ENV === 'development' && '@hyperse/inspector-babel-plugin', // Filter out falsy values in case NODE_ENV is not 'development' ].filter(Boolean), };
For SWC Users (@hyperse/inspector-swc-plugin)
Add @hyperse/inspector-swc-plugin to your SWC configuration (e.g., .swcrc or within your bundler's SWC loader options).
Example for .swcrc:
{ "jsc": { "parser": { "syntax": "typescript", "tsx": true }, "transform": { "react": { "runtime": "automatic" } }, "experimental": { "plugins": [["@hyperse/inspector-swc-plugin", {}]] } } }
Note: Ensure the SWC plugin is only applied in development if configuring through bundler options.
Step 4: Configure the Dev Server Middleware
The middleware listens for requests from the inspector component and launches your IDE.
Next.js
For Next.js projects, you can use the official @hyperse/next-inspector plugin. Here's how to configure it:
// next.config.mjs import { resolve } from 'path'; import { createNextConfig } from '@hyperse/next-config'; import withNextInspector from '@hyperse/next-inspector/plugin'; const plugins = [ withNextInspector({ projectCwd: resolve(process.cwd()), trustedEditor: 'cursor', // or 'vscode', 'webstorm', etc. customLaunchEditorEndpoint: '/hps_inspector', keys: ['$mod', 'g'], // Customize hotkeys hideDomPathAttr: false, }), ]; const nextConfig = { // Your Next.js config options }; export default createNextConfig(nextConfig, plugins);
Key configuration options for Next.js:
projectCwd: Your project's root directorytrustedEditor: Your preferred IDE (e.g., 'cursor', 'vscode', 'webstorm')customLaunchEditorEndpoint: Custom endpoint for launching the editorkeys: Custom hotkey configurationhideDomPathAttr: Whether to hide DOM path attributes in production
Webpack
In your webpack.config.js (or equivalent for development):
// webpack.config.js const { createInspectorMiddleware } = require('@hyperse/inspector-middleware'); module.exports = (env, argv) => { const isDev = argv.mode === 'development'; return { // ... other webpack config devServer: { // ... other devServer config setupMiddlewares: (middlewares, devServer) => { if (isDev) { /** * @hyperse/inspector server middleware */ middlewares.unshift(createInspectorMiddleware({})); } // Your other middlewares return middlewares; }, }, module: { rules: [ // Example for Babel loader (ensure Step 3 is configured) { test: /\.(js|jsx|ts|tsx)$/, exclude: /node_modules/, use: { loader: 'babel-loader', // Babel options can be here or in babel.config.js }, }, // Example for SWC loader (ensure Step 3 is configured if using .swcrc, or configure plugin here) // { // test: /\.tsx?$/, // exclude: /node_modules/, // use: { // loader: 'swc-loader', // or 'builtin:swc-loader' for Rspack/Turbopack // options: { // SWC options, including the plugin if not using .swcrc // jsc: { // experimental: { // plugins: isDev ? [['@hyperse/inspector-swc-plugin', {}]] : [], // }, // // ... other jsc options // }, // }, // }, // }, ], }, // ... other webpack config }; };
Vite
In your vite.config.ts (or .js):
// vite.config.ts import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import { createInspectorMiddleware } from '@hyperse/inspector-middleware'; // Corrected package export default defineConfig(({ mode }) => { const isDevelopment = mode === 'development'; return { plugins: [ react({ // If using Babel for JSX transformation with Vite: babel: { plugins: [isDevelopment && '@hyperse/inspector-babel-plugin'].filter( Boolean ), }, // If using SWC (default for @vitejs/plugin-react v3+), // ensure @hyperse/inspector-swc-plugin is in your .swcrc // or configure it via swc options if available in plugin-react. }), // Middleware for @hyperse/inspector isDevelopment && { name: 'hyperse-inspector-middleware', configureServer(server) { server.middlewares.use(createInspectorMiddleware({})); }, }, ].filter(Boolean), // ... other Vite config }; });
For SWC with Vite: If @vitejs/plugin-react uses SWC, ensure @hyperse/inspector-swc-plugin is configured in your project's .swcrc file. Vite's React plugin will pick it up.
Rspack
In your rspack.config.js (or equivalent for development):
// rspack.config.js const { createInspectorMiddleware } = require('@hyperse/inspector-middleware'); module.exports = (env, argv) => { const isDev = process.env.NODE_ENV === 'development'; // Rspack often uses NODE_ENV return { // ... other Rspack config devServer: { // ... other devServer config setupMiddlewares: (middlewares, devServer) => { if (isDev) { /** * @hyperse/inspector server middleware */ middlewares.unshift(createInspectorMiddleware({})); } // Your other middlewares return middlewares; }, }, module: { rules: [ // Example for builtin:swc-loader (ensure Step 3 is configured for SWC) { test: /\.(js|jsx|ts|tsx)$/, exclude: /node_modules/, loader: 'builtin:swc-loader', options: { jsc: { parser: { syntax: 'typescript', tsx: true }, transform: { react: { runtime: 'automatic' } }, experimental: { plugins: isDev ? [['@hyperse/inspector-swc-plugin', {}]] : [], }, }, }, }, ], }, // ... other Rspack config }; };
Customization
Custom Hotkeys
You can customize the activation hotkeys by passing the keys prop to the <Inspector /> component.
The keys prop accepts an array of strings representing KeyboardEvent.key values.
<Inspector keys={['Shift', 'Alt', 'c']} />
This will set the hotkey to Shift + Alt + c.
Controlled Mode
For more fine-grained control over the inspector's visibility, you can use the active and onActiveChange props.
import { Inspector } from '@hyperse/inspector'; import { useState } from 'react'; function MyComponent() { const [showInspector, setShowInspector] = useState(false); return ( <> <button onClick={() => setShowInspector(!showInspector)}> Toggle Inspector Programmatically </button> <Inspector active={showInspector} onActiveChange={setShowInspector} // You can still provide custom keys or use default /> </> ); }
How It Works
Here's a simplified overview of the @hyperse/inspector pipeline:
sequenceDiagram autonumber participant Dev as Developer Browser participant UI as Inspector Component (client) participant Trans as Babel/SWC Plugin (build) participant MW as Dev Server Middleware participant Launch as Launcher (e.g., launch-editor) participant IDE as IDE rect rgb(240,245,255) note over Trans: Build-time transformation Trans->>Trans: Inject data-hps-* attrs (filename:line:col) end Dev->>UI: Press hotkey / click inspect UI->>MW: HTTP request with file, line, column alt Valid request MW->>Launch: Spawn editor with file:line:col Launch->>IDE: Open at location IDE-->>Dev: File focused at target else Invalid/unknown MW-->>UI: Error response UI-->>Dev: Show error state end
-
Part 0: JSX Source Information (Build-time)
- This step is typically handled by your existing React setup (e.g., via Babel's
babel-plugin-transform-react-jsx-sourceor SWC's equivalent functionality). It adds__source(file path, line number) debug information to JSX elements. - The
@hyperse/inspector-babel-pluginor@hyperse/inspector-swc-pluginleverages this or injects similar information, ensuring it's consistently available and formatted for the inspector.
- This step is typically handled by your existing React setup (e.g., via Babel's
-
Part 1: Inspector Component (Client-side)
- The
<Inspector />component, when activated (e.g., by hotkey), allows you to select an element on the page. - Upon selection, it reads the source location information (file path, line, column) embedded in the selected React component's DOM element or Fiber node.
- It then sends an API request to your development server, containing this source path information.
- The
-
Part 2: Dev Server Middleware (Server-side)
- The
@hyperse/inspector-middleware(e.g.,createInspectorMiddleware) runs on your development server. - It listens for API requests from the client-side Inspector.
- When it receives a request, it uses a launcher utility (like
launch-editor) to open the specified source file in your configured local IDE/Editor, navigating directly to the correct line and column.
- The
Supported IDEs/Editors
@hyperse/inspector uses launch-editor (or a similar mechanism) under the hood, which supports a wide range of popular IDEs and editors. Commonly supported ones include:
- Visual Studio Code (VS Code)
- WebStorm / IntelliJ IDEA / PhpStorm / PyCharm (and other JetBrains IDEs)
- Sublime Text
- Atom
- Vim / Neovim
- Emacs
- And more...
Ensure your chosen IDE is correctly configured in your system's environment variables (e.g., LAUNCH_EDITOR or EDITOR) or that its command-line interface (CLI) is in your system's PATH. For VS Code, simply having code in your PATH is usually sufficient.
Troubleshooting
- Inspector not opening files / "Editor not found":
- Ensure your IDE's command-line tool is installed and added to your system's PATH (e.g.,
codefor VS Code). - You might need to set the
LAUNCH_EDITORorEDITORenvironment variable. For example, in your.bashrcor.zshrc:export LAUNCH_EDITOR=code # For VS Code # export LAUNCH_EDITOR=webstorm # For WebStorm - Restart your development server and terminal after making changes to environment variables.
- Ensure your IDE's command-line tool is installed and added to your system's PATH (e.g.,
- Component source not found / incorrect location:
- Verify that the Babel or SWC plugin is correctly configured and running only in development mode.
- Ensure source maps are being generated correctly if the plugin relies on them indirectly.
- Check for any conflicting Babel/SWC plugins that might interfere with source information.
License
This project is licensed under the MIT LICENSE.