Next.js starter your AI actually understands. Ship internal tools in days not weeks. Pre-order $199 $499 → [Get it now]

How to document components in React

Documenting React components is a critical task that ensures your codebase remains maintainable, scalable, and accessible to other developers. With over 25 years of experience in software development and as the creator of CoreUI, I’ve built and documented hundreds of complex components for millions of users worldwide. From my expertise, the most efficient approach is a multi-layered strategy combining JSDoc for inline descriptions, TypeScript for structural type safety, and Storybook for visual documentation. This combination provides immediate feedback in modern IDEs and creates a live style guide for your entire design system.

Use JSDoc comments for descriptive metadata and TypeScript interfaces to define the structural contract of your React components.

Section 1: Documenting with JSDoc

JSDoc is the industry standard for adding descriptive comments to JavaScript code, providing hover information and autocomplete suggestions directly in editors like VS Code.

import React from 'react'

/**
 * A reusable Button component that supports various themes and sizes.
 * Use this component for primary user actions throughout the application.
 *
 * @param {Object} props - The properties passed to the component.
 * @param {string} props.color - The background color theme (e.g., 'primary', 'success').
 * @param {boolean} [props.disabled=false] - If true, the button will be non-interactive.
 * @param {React.ReactNode} props.children - The content to be rendered inside the button.
 * @returns {JSX.Element} The rendered button component.
 */
const CustomButton = ({ color, disabled, children }) => {
  return (
    <button 
      className={`btn btn-${color}`} 
      disabled={disabled}
    >
      {children}
    </button>
  )
}

export default CustomButton

In this example, the block comment starting with /** allows tools to parse the description and parameters. This is the same method we use in CoreUI Buttons to ensure every prop is clearly explained to the developer.

Section 2: Using TypeScript for Self-Documenting Code

TypeScript is the most powerful tool for documenting React components because it enforces the documentation at compile-time, preventing mismatched props and types.

import React from 'react'

interface AlertProps {
  /** The message to display inside the alert box */
  message: string
  /** 
   * The visual style of the alert. 
   * @default 'info' 
   */
  variant?: 'success' | 'danger' | 'warning' | 'info'
  /** Optional callback triggered when the user closes the alert */
  onClose?: () => void
}

/**
 * Alert component used to provide feedback to the user.
 * It supports multiple variants to indicate the nature of the message.
 */
const Alert: React.FC<AlertProps> = ({ message, variant = 'info', onClose }) => {
  return (
    <div className={`alert alert-${variant}`}>
      {message}
      {onClose && <button onClick={onClose}>&times;</button>}
    </div>
  )
}

export default Alert

By defining an interface or type, you create a formal contract. IDEs will automatically show the comments added inside the interface when you hover over the prop names in your JSX code. This reduces the need to switch between files to understand how a component works.

Section 3: Visual Documentation with Storybook

Storybook allows you to document components in isolation, creating a visual catalog where developers can interact with different states and edge cases.

import CustomButton from './CustomButton'

export default {
  title: 'Components/CustomButton',
  component: CustomButton,
  argTypes: {
    color: { control: 'color' },
    disabled: { control: 'boolean' },
  },
}

export const Primary = {
  args: {
    color: 'primary',
    children: 'Click Me',
  },
}

export const Disabled = {
  args: {
    color: 'secondary',
    disabled: true,
    children: 'Locked',
  },
}

Storybook serves as a “live” documentation site. It’s particularly useful for complex elements like CoreUI Modals, where you need to see how the component behaves in different viewports and configurations without running the entire application.

Section 4: Documenting Component Hooks

When creating custom hooks for your components, documenting the return values and input parameters is essential for clarity and reuse.

import { useState, useCallback } from 'react'

/**
 * Custom hook to manage the toggle state of UI elements like Modals or Dropdowns.
 * 
 * @param {boolean} initialState - The starting visibility state.
 * @returns {[boolean, () => void]} A tuple containing the visibility state and a toggle function.
 */
export const useToggle = (initialState: boolean = false): [boolean, () => void] => {
  const [isOpen, setIsOpen] = useState(initialState)

  const toggle = useCallback(() => {
    setIsOpen((prev) => !prev)
  }, [])

  return [isOpen, toggle]
}

Documenting hooks ensures that utility logic remains transparent. For instance, if you are building a component that needs to format a number as currency, documenting the transformation logic inside the hook prevents bugs and duplicate code.

Section 5: README Files for High-Level Overview

Every complex component or component folder should have a README.md to explain the “Why” and provide quick-start examples that code comments might not cover effectively.

# SmartTable Component

The `SmartTable` is a data-grid component designed for large datasets. 
It supports sorting, filtering, and pagination out of the box.

## Installation
```bash
npm install @coreui/react-pro

Basic Usage

import { CSmartTable } from '@coreui/react-pro'

const MyPage = () => (
  <CSmartTable 
    items={items} 
    columns={['name', 'email', 'status']} 
  />
)

Internal References


Markdown files are the best place for architectural notes, installation instructions, and linking to related utilities. This structured approach is what makes our [Admin Dashboard Template](/product/admin-dashboard-template/) so easy for teams to adopt quickly.

## Section 6: PropTypes for Runtime Validation
While TypeScript handles compile-time checks, PropTypes provide runtime warnings in the browser console, which is helpful during development for teams not using TypeScript.

```jsx
import React from 'react'
import PropTypes from 'prop-types'

const Badge = ({ children, color }) => (
  <span className={`badge bg-${color}`}>
    {children}
  </span>
)

Badge.propTypes = {
  /** The content of the badge */
  children: PropTypes.node.isRequired,
  /** The background color variant */
  color: PropTypes.oneOf(['primary', 'secondary', 'success', 'danger', 'info', 'light', 'dark']),
}

Badge.defaultProps = {
  color: 'primary',
}

export default Badge

PropTypes act as a living documentation of your component’s expectations. If a developer passes a number where a string is expected, the browser console will provide a clear error message, making debugging significantly faster.

Best Practice Note:

Consistency is more important than the specific tool you choose. At CoreUI, we recommend using TypeScript as your primary documentation source because it provides the most “bang for your buck” by combining types and documentation into a single source of truth. Always include a short JSDoc description for exported components to help your team understand the intent behind the code without having to read the implementation details.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author

Subscribe to our newsletter
Get early information about new products, product updates and blog posts.
How to Add a Tab in HTML
How to Add a Tab in HTML

How to show or hide elements in React? A Step-by-Step Guide.
How to show or hide elements in React? A Step-by-Step Guide.

How to get element ID in JavaScript
How to get element ID in JavaScript

How to Use Bootstrap Tooltip in Vue 3 – The Right Way with CoreUI
How to Use Bootstrap Tooltip in Vue 3 – The Right Way with CoreUI

Answers by CoreUI Core Team