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

is-react-comp

v1.0.3

Published

![npm version](https://img.shields.io/npm/v/is-react-comp) ![License](https://img.shields.io/npm/l/is-react-comp) ![TypeScript](https://img.shields.io/badge/TypeScript-4%2B-blue) ![JavaScript](https://img.shields.io/badge/JavaScript-ES6%2B-yellow

Readme

is-react-comp

npm version
License
TypeScript
JavaScript
React

Production-grade utilities for validating and working with React components at runtime. Compatible with all React versions from 16.8+ and works with both TypeScript and JavaScript projects.


What does this do?

Sometimes you have a variable and you're not sure if it's a React component or not. This package helps you figure that out!

It works with:

  • ✅ Regular function components
  • ✅ Class components
  • ✅ Components wrapped in memo()
  • ✅ Components wrapped in forwardRef()
  • ✅ Lazy-loaded components
  • ✅ React elements (optional)

Quick Start

Install it

npm install is-react-comp

# yarn
yarn add is-react-comp

# pnpm
pnpm add is-react-comp

# bun
bun add is-react-comp

Use it

import { isReactComponent } from 'is-react-comp';

function MyComponent() {
  return <div>Hello!</div>;
}

// Check if it's a React component
if (isReactComponent(MyComponent)) {
  console.log('Yep, this is a React component! 🎉');
}

// Works with regular variables too
const something = getSomethingFromSomewhere();
if (isReactComponent(something)) {
  // It's safe to render it
  return <something />;
}

What else can you do?

Get info about a component

import { getReactComponentInfo } from 'is-react-comp';

const info = getReactComponentInfo(MyComponent);
console.log(info.componentType); // "function", "class", "memo", etc.
console.log(info.displayName);   // "MyComponent"

Check for specific types

import { 
  isFunctionComponent,
  isClassComponent,
  isMemoComponent 
} from 'is-react-comp';

if (isFunctionComponent(MyComponent)) {
  console.log('This is a function component');
}

Use in React components

import { useIsComponent } from 'is-react-comp';

function MyWrapper({ children }) {
  const { isComponent } = useIsComponent(children);
  
  if (!isComponent) {
    return <div>Not a valid component!</div>;
  }
  
  return children;
}

Complete Examples

Function Component

import { isReactComponent, isFunctionComponent } from 'is-react-comp';

function MyButton({ text }) {
  return <button>{text}</button>;
}

console.log(isReactComponent(MyButton));        // true
console.log(isFunctionComponent(MyButton));     // true

Class Component

import { isReactComponent, isClassComponent } from 'is-react-comp';

class MyCounter extends React.Component {
  render() {
    return <div>Count: {this.props.count}</div>;
  }
}

console.log(isReactComponent(MyCounter));       // true
console.log(isClassComponent(MyCounter));        // true

Memo Component

import { isReactComponent, isMemoComponent } from 'is-react-comp';

const ExpensiveComponent = React.memo(function({ data }) {
  return <div>{data.map(item => <span key={item.id}>{item.name}</span>)}</div>;
});

console.log(isReactComponent(ExpensiveComponent));    // true
console.log(isMemoComponent(ExpensiveComponent));     // true

ForwardRef Component

import { isReactComponent, isForwardRefComponent } from 'is-react-comp';

const MyInput = React.forwardRef((props, ref) => {
  return <input ref={ref} {...props} />;
});

console.log(isReactComponent(MyInput));               // true
console.log(isForwardRefComponent(MyInput));          // true

Lazy Component

import { isReactComponent, isLazyComponent } from 'is-react-comp';

const LazyComponent = React.lazy(() => import('./MyComponent'));

console.log(isReactComponent(LazyComponent));         // true
console.log(isLazyComponent(LazyComponent));          // true

React Elements

import { isReactComponent, isReactElement } from 'is-react-comp';

const element = <div>Hello World</div>;
const component = function() { return <div>Hello</div>; };

console.log(isReactElement(element));                 // true
console.log(isReactElement(component));               // false

// Include elements in component check
console.log(isReactComponent(element, { includeElements: true }));  // true
console.log(isReactComponent(component, { includeElements: true })); // true

Real-World Plugin System Example

import { isReactComponent, getReactComponentInfo } from 'is-react-comp';

function PluginRenderer({ plugins }) {
  return plugins.map((plugin, index) => {
    // Validate each plugin is a React component
    if (!isReactComponent(plugin.component)) {
      console.error(`Plugin ${index} is not a valid React component`);
      return <div key={index}>Invalid plugin component</div>;
    }
    
    const info = getReactComponentInfo(plugin.component);
    
    return (
      <div key={index}>
        <h3>{plugin.name}</h3>
        <p>Type: {info.componentType}</p>
        <plugin.component {...plugin.props} />
      </div>
    );
  });
}

// Usage
const plugins = [
  {
    name: 'Header',
    component: () => <header>My App</header>,
    props: {}
  },
  {
    name: 'Footer', 
    component: React.memo(() => <footer>© 2024</footer>),
    props: {}
  }
];

<PluginRenderer plugins={plugins} />

Component Validation with Fallback

import { withComponentValidation } from 'is-react-comp';

// Your regular component
function UserProfile({ user }) {
  return (
    <div>
      <h2>{user.name}</h2>
      <p>{user.email}</p>
    </div>
  );
}

// Wrap with validation and fallback
const SafeUserProfile = withComponentValidation(UserProfile, {
  fallback: <div className="error">Failed to load user profile</div>,
  strict: true
});

// Usage - will show fallback if UserProfile is invalid
function App({ profileComponent }) {
  return <SafeUserProfile user={{ name: 'John', email: '[email protected]' }} />;
}

// Dynamic component example
function DynamicComponentLoader({ component, fallback }) {
  const SafeComponent = withComponentValidation(component, {
    fallback: fallback || <div>Component not available</div>
  });
  
  return <SafeComponent />;
}

// Usage with potentially invalid component
const maybeInvalid = null; // Could be anything
<DynamicComponentLoader 
  component={maybeInvalid}
  fallback={<div className="loading-error">Component failed to load</div>}
/>

Advanced Fallback Examples

import { withComponentValidation } from 'is-react-comp';

// Custom fallback component
function ErrorFallback({ error, componentName }) {
  return (
    <div className="component-error">
      <h3>⚠️ Component Error</h3>
      <p>Failed to render: {componentName}</p>
      {error && <p>Error: {error.message}</p>}
    </div>
  );
}

// Loading fallback
function LoadingFallback() {
  return (
    <div className="loading">
      <div className="spinner"></div>
      <p>Loading component...</p>
    </div>
  );
}

// Wrap components with different fallbacks
const SafeHeader = withComponentValidation(HeaderComponent, {
  fallback: <ErrorFallback componentName="Header" />
});

const SafeLazyComponent = withComponentValidation(LazyComponent, {
  fallback: <LoadingFallback />
});

// Conditional fallback based on component type
function smartFallback(component) {
  const info = getReactComponentInfo(component);
  
  if (info.componentType === 'lazy') {
    return <LoadingFallback />;
  } else {
    return <ErrorFallback componentName={info.displayName || 'Unknown'} />;
  }
}

const SmartSafeComponent = withComponentValidation(SomeComponent, {
  fallback: smartFallback(SomeComponent)
});

Why would you need this?

  • Plugin systems: When users can pass in custom components
  • Dynamic rendering: When you're not sure what you're getting
  • Debugging: To figure out what type of component you're working with
  • Component libraries: To validate user input

Options

You can customize how it works:

// Include React elements as components too
isReactComponent(something, { includeElements: true });

// Less strict checking (might have false positives)
isReactComponent(something, { strict: false });

TypeScript Support

If you're using TypeScript, you get automatic type checking:

import { isReactComponent } from 'is-react-comp';

function doSomething(value: unknown) {
  if (isReactComponent(value)) {
    // TypeScript now knows this is a React component!
    return <value />;
  }
}

That's it!

No complicated setup, no weird dependencies. Just a simple tool that does one thing well.

Questions? Open an issue


License

MIT © Nikhil Kumar