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

nextjs-ide-helper

v1.5.4

Published

A Next.js plugin that automatically adds IDE buttons to React components for seamless IDE integration. Supports Cursor, VS Code, WebStorm, and Atom.

Readme

NextJS IDE Helper

A Next.js plugin that automatically adds IDE buttons to React components in development mode, enabling seamless IDE integration and faster development workflow. Supports Cursor, VS Code, WebStorm, and Atom.

Features

  • 🚀 Automatic Integration: Automatically wraps React components with IDE buttons
  • 🎯 Smart Detection: Only processes components in specified directories
  • 🔧 Zero Configuration: Works out of the box with sensible defaults (Cursor as default IDE)
  • 🏎️ Development Only: Only active in development mode, no production overhead
  • 🎨 Non-intrusive: Minimal blue dot indicators that don't disrupt your layout
  • 👁️ Toggle Visibility: Floating button to show/hide all IDE dots instantly
  • Hydration Safe: No SSR/client hydration mismatches
  • 📱 TypeScript Support: Full TypeScript definitions included
  • 🔌 Multi-IDE Support: Supports Cursor, VS Code, WebStorm, and Atom
  • 🎭 Multiple Component Patterns: Supports all React component export patterns
  • 🔍 AST-Based Processing: Uses robust Abstract Syntax Tree parsing for accurate code transformation

Installation

npm install nextjs-ide-helper

Quick Start

1. Configure Next.js

Add the plugin to your next.config.js:

const withIdeHelper = require('nextjs-ide-helper');

/** @type {import('next').NextConfig} */
const nextConfig = {
  // your existing config
};

module.exports = withIdeHelper()(nextConfig);

2. That's it!

All React components in your src/components directory will automatically get IDE buttons in development mode (defaults to Cursor IDE).

User Interface

IDE Indicator Dots

Each wrapped component displays a small blue dot (10x10px) in the top-right corner:

  • Click the dot to open the component's source file in your IDE
  • Hover to see the file path tooltip
  • The dots are subtle (60% opacity) and brighten on hover

Toggle Button

A floating toggle button appears in the bottom-right corner of your page:

  • Blue = IDE dots are visible
  • Gray = IDE dots are hidden
  • Click to toggle all dots on/off instantly

This lets you quickly hide the dots when you want an unobstructed view of your app, then bring them back when needed.

Configuration

You can customize the plugin behavior:

const withIdeHelper = require('nextjs-ide-helper');

const nextConfig = {
  // your existing config
};

module.exports = withIdeHelper({
  componentPaths: ['src/components', 'components', 'src/ui'], // directories to scan (supports glob patterns)
  projectRoot: process.cwd(), // project root directory
  importPath: 'nextjs-ide-helper/withIdeButton', // import path for the HOC
  enabled: process.env.NODE_ENV === 'development', // enable/disable
  ideType: 'cursor' // IDE to use: 'cursor', 'vscode', 'webstorm', 'atom'
})(nextConfig);

Configuration Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | componentPaths | string[] | ['src/components'] | Directories to scan for React components (supports glob patterns) | | projectRoot | string | process.cwd() | Root directory of your project | | importPath | string | 'nextjs-ide-helper/withIdeButton' | Import path for the withIdeButton HOC | | enabled | boolean | process.env.NODE_ENV === 'development' | Enable/disable the plugin | | ideType | 'cursor' \| 'vscode' \| 'webstorm' \| 'atom' | 'cursor' | IDE to open files in |

Glob Pattern Support

The componentPaths option supports glob patterns for matching nested directory structures:

module.exports = withIdeHelper({
  componentPaths: [
    'src/components/**',           // matches all nested directories under src/components
    '**/components/**',           // matches components directories anywhere in the project
    'app/**/ui/**',               // matches ui directories nested anywhere under app
    'modules/*/components/**'     // matches components in any module subdirectory
  ]
})(nextConfig);

Glob Pattern Examples:

  • * - matches any characters within a single directory level
  • ** - matches any number of directories and subdirectories recursively
  • src/components/* - matches src/components/Button.tsx but not src/components/ui/Button.tsx
  • src/components/** - matches both src/components/Button.tsx and src/components/ui/forms/Button.tsx
  • **/components/** - matches app/components/Button.tsx, modules/feature/components/deep/Widget.tsx, etc.

Manual Usage

You can also manually wrap components:

import { withIdeButton } from 'nextjs-ide-helper';

const MyComponent = () => {
  return <div>Hello World</div>;
};

// Default (Cursor)
export default withIdeButton(MyComponent, 'src/components/MyComponent.tsx');

// With specific IDE
export default withIdeButton(MyComponent, 'src/components/MyComponent.tsx', {
  ideType: 'vscode'
});

Supported Component Patterns

The plugin automatically detects and wraps all types of React component export patterns:

Named Export Components

// Named arrow function exports
export const Button = () => <button>Click me</button>;
export const Modal = () => <div>Modal content</div>;

// Named function exports
export function MyButton() {
  return <button>Function Button</button>;
}

export function MyModal() {
  return <div>Function Modal</div>;
}

// Mixed named and default exports
export const HeaderButton = () => <button>Header</button>;

const MainComponent = () => <div>Main</div>;
export default MainComponent;

// TypeScript named exports
interface ButtonProps {
  onClick: () => void;
}

export const TypedButton = ({ onClick }: ButtonProps) => (
  <button onClick={onClick}>Typed Button</button>
);

Default Export Components

Named Components

// Standard pattern
const MyComponent = () => <div>Hello</div>;
export default MyComponent;

// Variable declaration
const MyComponent = function() {
  return <div>Hello</div>;
};
export default MyComponent;

Direct Export Function Components

// Named function
export default function MyComponent() {
  return <div>Hello</div>;
}

// Anonymous function
export default function() {
  return <div>Hello</div>;
}

Arrow Function Components

// Anonymous arrow function
export default () => {
  return <div>Hello</div>;
};

// Arrow function with parameters
export default (props) => {
  return <div>Hello {props.name}</div>;
};

Class Components

// Named class
export default class MyComponent extends React.Component {
  render() {
    return <div>Hello</div>;
  }
}

// TypeScript class
export default class MyComponent extends Component<Props> {
  render() {
    return <div>Hello</div>;
  }
}

TypeScript Components

// Function with TypeScript
interface Props {
  title: string;
}

export default function MyComponent(props: Props) {
  return <div>{props.title}</div>;
}

// Arrow function with TypeScript
export default (props: Props) => {
  return <div>{props.title}</div>;
};

How It Works

  1. AST-Based Processing: Uses Babel's Abstract Syntax Tree parser for robust code analysis
  2. Webpack Loader: The plugin uses a custom webpack loader to transform your React components at build time
  3. Automatic Detection: It scans specified directories for .tsx and .jsx files
  4. Smart Wrapping: Only wraps components that export a default React component (PascalCase names)
  5. Development Only: The IDE buttons only appear in development mode
  6. Hydration Safe: Uses client-side state to prevent SSR/hydration mismatches

Examples

Standard Component Pattern

Before (your original component):

// src/components/Button.tsx
import React from 'react';

const Button = ({ children, onClick }) => {
  return (
    <button onClick={onClick}>
      {children}
    </button>
  );
};

export default Button;

After (automatically transformed):

// src/components/Button.tsx (transformed by the plugin)
import React from 'react';
import { withIdeButton } from 'nextjs-ide-helper/withIdeButton';

const Button = ({ children, onClick }) => {
  return (
    <button onClick={onClick}>
      {children}
    </button>
  );
};

export default withIdeButton(Button, 'src/components/Button.tsx', { 
  projectRoot: '/path/to/project',
  ideType: 'cursor'
});

Named Export Pattern

Before (your original named exports):

// src/components/Buttons.tsx
export const PrimaryButton = ({ children, onClick }) => {
  return (
    <button className="primary" onClick={onClick}>
      {children}
    </button>
  );
};

export const SecondaryButton = ({ children, onClick }) => {
  return (
    <button className="secondary" onClick={onClick}>
      {children}
    </button>
  );
};

After (automatically transformed):

// src/components/Buttons.tsx (transformed by the plugin)
import { withIdeButton } from 'nextjs-ide-helper/withIdeButton';

export const PrimaryButton = withIdeButton(({ children, onClick }) => {
  return (
    <button className="primary" onClick={onClick}>
      {children}
    </button>
  );
}, 'src/components/Buttons.tsx', {
  projectRoot: '/path/to/project',
  ideType: 'cursor'
});

export const SecondaryButton = withIdeButton(({ children, onClick }) => {
  return (
    <button className="secondary" onClick={onClick}>
      {children}
    </button>
  );
}, 'src/components/Buttons.tsx', {
  projectRoot: '/path/to/project',
  ideType: 'cursor'
});

Mixed Named and Default Exports

Before (mixed exports):

// src/components/Layout.tsx
export const Header = () => <header>My App Header</header>;
export const Footer = () => <footer>© 2025 My App</footer>;

const Layout = ({ children }) => (
  <div>
    <Header />
    <main>{children}</main>
    <Footer />
  </div>
);

export default Layout;

After (automatically transformed):

// src/components/Layout.tsx (transformed by the plugin)
import { withIdeButton } from 'nextjs-ide-helper/withIdeButton';

export const Header = withIdeButton(() => <header>My App Header</header>, 'src/components/Layout.tsx', {
  projectRoot: '/path/to/project',
  ideType: 'cursor'
});

export const Footer = withIdeButton(() => <footer>© 2025 My App</footer>, 'src/components/Layout.tsx', {
  projectRoot: '/path/to/project',
  ideType: 'cursor'
});

const Layout = ({ children }) => (
  <div>
    <Header />
    <main>{children}</main>
    <Footer />
  </div>
);

export default withIdeButton(Layout, 'src/components/Layout.tsx', {
  projectRoot: '/path/to/project',
  ideType: 'cursor'
});

Direct Export Function Component

Before:

// src/components/Header.tsx
export default function Header() {
  return <header>My App Header</header>;
}

After (automatically transformed):

// src/components/Header.tsx (transformed by the plugin)
import { withIdeButton } from 'nextjs-ide-helper/withIdeButton';

function Header() {
  return <header>My App Header</header>;
}

export default withIdeButton(Header, 'src/components/Header.tsx', {
  projectRoot: '/path/to/project',
  ideType: 'cursor'
});

Anonymous Component

Before:

// src/components/Footer.tsx
export default () => {
  return <footer>© 2025 My App</footer>;
};

After (automatically transformed):

// src/components/Footer.tsx (transformed by the plugin)
import { withIdeButton } from 'nextjs-ide-helper/withIdeButton';

export default withIdeButton(() => {
  return <footer>© 2025 My App</footer>;
}, 'src/components/Footer.tsx', {
  projectRoot: '/path/to/project',
  ideType: 'cursor'
});

Troubleshooting

Components not getting wrapped

  1. Check that your components are in the specified componentPaths
  2. Ensure your components export a default export with a capitalized name
  3. Verify you're in development mode (NODE_ENV=development)

Hydration errors

The plugin is designed to prevent hydration errors, but if you encounter any:

  1. Make sure you're using the latest version
  2. Check that the 'use client' directive is present in the withIdeButton module
  3. File an issue with details about your setup

IDE not opening files

  1. Ensure you have your IDE installed and properly configured
    • Cursor: Make sure Cursor IDE is installed
    • VS Code: Make sure VS Code is installed and set up to handle vscode:// links
    • WebStorm: Ensure WebStorm is installed and configured
    • Atom: Make sure Atom is installed (note: Atom is deprecated)
  2. Check that the file paths are correct
  3. Verify your browser allows protocol links for your IDE
  4. Try setting the ideType option explicitly in your configuration

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT

Changelog

See CHANGELOG.md for detailed release notes.

Recent Releases

1.5.0 - Toggle Visibility

  • Added floating toggle button to show/hide all IDE dots
  • Toggle button appears in bottom-right corner
  • Blue when dots visible, gray when hidden
  • State synchronized across all components via custom events

1.4.1 - Minimal UI

  • Changed IDE buttons from text+emoji to minimal 10x10px blue dots
  • Reduced visual footprint for less intrusive development experience
  • Removed console.log statements from plugin

1.4.0 - Named Export Support

  • Added comprehensive support for ES6 named exports in React components
  • Support for export const Component = () => {} and export function Component() {} patterns
  • Mixed export support - files with both named and default exports
  • Enhanced component detection to distinguish React components from utility exports
  • Expanded test suite with 8 new comprehensive test cases

1.3.0 - Glob Pattern Support

  • Added support for glob patterns in componentPaths configuration
  • Support for nested directory matching with ** patterns
  • Enhanced file path matching for complex project structures
  • Updated tests and documentation

1.2.0 - Enhanced Component Support

  • Added support for all React component export patterns
  • AST-based code transformation for better reliability
  • Anonymous component support
  • Enhanced TypeScript compatibility

1.1.3

  • Updated readme

1.1.2

  • Added support for multiple IDEs (Cursor, VS Code, WebStorm, Atom)

1.0.0

  • Initial release
  • Automatic component wrapping
  • TypeScript support
  • Hydration-safe implementation