react-accessible-accordion vs react-collapse vs react-collapsible
React Libraries for Accessible Collapsible Components
react-accessible-accordionreact-collapsereact-collapsible

React Libraries for Accessible Collapsible Components

react-accessible-accordion, react-collapse, and react-collapsible are React libraries designed to create collapsible UI components such as accordions, expandable panels, and toggleable sections. These packages help developers show or hide content based on user interaction while managing animation, state, and — in some cases — accessibility concerns. Each library takes a different approach: react-accessible-accordion emphasizes WAI-ARIA compliance and built-in keyboard navigation; react-collapse offers a minimal, unopinionated collapse primitive focused on smooth animation; and react-collapsible provides a simple, self-contained toggle component with basic styling and animation but limited accessibility support.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
react-accessible-accordion0785108 kB29a year agoMIT
react-collapse01,13472.6 kB105 years agoMIT
react-collapsible054745.3 kB33-MIT

Building Accessible Accordions in React: react-accessible-accordion vs react-collapse vs react-collapsible

When you need to show and hide content in a UI — like FAQs, settings panels, or product details — collapsible components are essential. But not all implementations handle accessibility, performance, or developer experience equally. Let’s compare three popular React packages for this task: react-accessible-accordion, react-collapse, and react-collapsible.

🧩 Core Philosophy: Accessibility-First vs Minimalist vs Legacy Simplicity

react-accessible-accordion is built from the ground up with WAI-ARIA standards in mind. It automatically manages ARIA attributes (aria-expanded, aria-controls, etc.), keyboard navigation (arrow keys, Home/End), and focus management. If your team prioritizes inclusive design and compliance (e.g., WCAG), this is the only one of the three that enforces accessibility by default.

// react-accessible-accordion
import {
  Accordion,
  AccordionItem,
  AccordionItemHeading,
  AccordionItemButton,
  AccordionItemPanel
} from 'react-accessible-accordion';

<Accordion>
  <AccordionItem>
    <AccordionItemHeading>
      <AccordionItemButton>FAQ #1</AccordionItemButton>
    </AccordionItemHeading>
    <AccordionItemPanel>
      <p>Answer goes here.</p>
    </AccordionItemPanel>
  </AccordionItem>
</Accordion>

react-collapse takes a minimalist, unopinionated approach. It provides a single <Collapse> component that animates height transitions using CSS transforms and requestAnimationFrame. It doesn’t include any accordion logic — you must manage open/closed state yourself. This gives you full control but shifts the burden of accessibility and interaction patterns to you.

// react-collapse
import Collapse from 'react-collapse';

function MyCollapsible({ isOpen }) {
  return (
    <div>
      <button onClick={() => setIsOpen(!isOpen)}>Toggle</button>
      <Collapse isOpened={isOpen}>
        <div>Content here</div>
      </Collapse>
    </div>
  );
}

react-collapsible offers a simple, self-contained toggle component with basic animation. It bundles the trigger button and panel together, reducing boilerplate compared to react-collapse. However, it lacks built-in ARIA support and requires manual implementation of keyboard navigation and screen reader announcements.

// react-collapsible
import Collapsible from 'react-collapsible';

<Collapsible trigger="Click me">
  <p>Hidden content</p>
</Collapsible>

♿ Accessibility Support: Out-of-the-Box vs DIY

Only react-accessible-accordion ships with full WAI-ARIA compliance:

  • Auto-generated unique IDs linking buttons to panels via aria-controls
  • aria-expanded toggled automatically
  • Arrow key navigation between items
  • Focus trapped within open panels (optional)
  • Screen reader-friendly semantics

In contrast, react-collapse and react-collapsible provide zero accessibility features. You must manually:

  • Add role="button" or use real <button> elements
  • Manage aria-expanded, aria-controls, and id associations
  • Implement keyboard handlers for Enter, Space, and arrow keys
  • Ensure focus order remains logical

Example of what you’d need to add manually with react-collapsible:

// Manual ARIA with react-collapsible (not built-in)
const [isOpen, setIsOpen] = useState(false);
const panelId = 'panel-' + Math.random().toString(36).substr(2, 9);

<>
  <button
    aria-expanded={isOpen}
    aria-controls={panelId}
    onClick={() => setIsOpen(!isOpen)}
  >
    Toggle
  </button>
  {isOpen && (
    <div id={panelId} role="region">
      <p>Content</p>
    </div>
  )}
</>

This extra work is error-prone and often neglected in practice — making react-accessible-accordion the safer choice for production apps where accessibility is non-negotiable.

⚙️ Animation and Performance

All three libraries animate height changes, but they do it differently:

  • react-accessible-accordion: Uses CSS transitions on max-height. Smooth but can be less performant with very tall content since max-height must be set to an estimated maximum.

  • react-collapse: Measures content height dynamically and uses transform: scaleY() combined with height for smoother, GPU-accelerated animations. More complex internally but better for variable or dynamic content.

  • react-collapsible: Relies on CSS max-height transitions similar to the first option. Simpler but shares the same limitation with unknown content heights.

If you’re animating large or dynamic content (e.g., user-generated text), react-collapse’s measurement-based approach avoids layout thrashing and feels more responsive.

🔁 State Management: Built-In vs External

react-accessible-accordion includes internal state management. You can let it handle which panels are open, or override behavior via props like preExpanded and onChange. It supports both single and multi-open modes out of the box.

react-collapse is completely stateless. You pass isOpened={true/false} and handle all logic yourself. This integrates cleanly with Redux, Zustand, or any state system but adds wiring overhead.

react-collapsible manages its own open/closed state internally but allows limited control via open and onOpen/onClose props. However, it doesn’t support controlled mode as robustly as the others — trying to force it closed from outside can lead to sync issues.

🛑 Maintenance Status and Deprecation Warnings

As of 2024:

  • react-accessible-accordion is actively maintained, with recent updates addressing React 18 compatibility and TypeScript improvements.

  • react-collapse is stable and maintained, though updates are infrequent. It works reliably with modern React versions.

  • react-collapsible shows signs of stagnation. Its last meaningful update was years ago, and it hasn’t been adapted for concurrent rendering patterns. While not officially deprecated, it lacks modern React best practices and should be avoided in new projects unless you’re maintaining legacy code.

🧪 Real-World Usage Scenarios

Scenario 1: Public-Facing FAQ Page (Accessibility Required)

Choose react-accessible-accordion

  • Compliance with legal accessibility standards (ADA, Section 508)
  • Keyboard and screen reader users get a seamless experience
  • Minimal dev effort to meet requirements

Scenario 2: Internal Admin Dashboard (Animation Quality Matters)

Choose react-collapse

  • You control all state via global store
  • Need smooth animations for dynamic content
  • Accessibility is lower priority (but still recommended!)

Scenario 3: Quick Prototype or Low-Stakes Side Project

⚠️ Avoid react-collapsible — even for prototypes, prefer react-accessible-accordion or react-collapse. The small convenience isn’t worth technical debt or accessibility gaps.

📊 Summary Table

Featurereact-accessible-accordionreact-collapsereact-collapsible
ARIA Compliance✅ Full, automatic❌ None❌ None
Keyboard Navigation✅ Built-in❌ Manual❌ Manual
Animation TechniqueCSS max-heightDynamic height + transformCSS max-height
State Management✅ Internal + controlled options❌ Fully external⚠️ Partial internal
Multi-Panel Support✅ Yes✅ (via your logic)✅ Yes
Maintenance Status✅ Active✅ Stable⚠️ Stale / Not recommended

💡 Final Recommendation

  • Default choice: react-accessible-accordion — it’s the only one that gets accessibility right without extra work.
  • Specialized use case: react-collapse — if you need pixel-perfect animations and already manage state externally.
  • Avoid: react-collapsible — outdated, incomplete accessibility, and no compelling advantage over the others.

Remember: accessible components aren’t just about compliance — they make your UI more robust, testable, and usable for everyone. Start with the right foundation.

How to Choose: react-accessible-accordion vs react-collapse vs react-collapsible

  • react-accessible-accordion:

    Choose react-accessible-accordion when building public-facing applications where accessibility compliance (WCAG, ADA) is required. It handles ARIA attributes, keyboard navigation, and focus management automatically, reducing the risk of accessibility bugs. Ideal for FAQs, documentation sites, or any interface that must work well with screen readers and keyboards without extra engineering effort.

  • react-collapse:

    Choose react-collapse when you need fine-grained control over animation performance and already manage component state externally (e.g., via Redux or context). It provides a lightweight, unstyled collapse primitive that works well for dashboards or internal tools where you can implement accessibility manually — but only if your team has the bandwidth to do so correctly.

  • react-collapsible:

    Avoid react-collapsible in new projects. While it offers a quick setup with minimal code, it lacks built-in accessibility features, hasn’t been actively maintained, and doesn’t follow modern React patterns. It may seem convenient for prototypes, but the technical debt and accessibility gaps outweigh its simplicity.

README for react-accessible-accordion

react-accessible-accordion npm Accessibility status

⚠️ Project status

In most cases, you no longer need a JS library like this to render fully functional, accessible accordions. For that reason, this project is no longer maintained.

This is because native HTML Disclosure (aka <details>/<summary>) elements are now widely supported.

Native disclosures offer several advantages over any JS-based solutions. For instance:

  • Because there is no JS to download/parse, they are far more performant.
  • They are framework-agnostic, and will work the same way whether you're using React, [other framework], or plain old HTML.
  • Collapsed content can still be found via find-on-page (ctrl/command+f) in supporting browsers, including Chrome.

Demo

Try a demo now.

Usage

First, grab the package from npm:

npm install --save react-accessible-accordion

Then, import the editor and use it in your code. Here is a basic example:

import React from 'react';

import {
    Accordion,
    AccordionItem,
    AccordionItemHeading,
    AccordionItemButton,
    AccordionItemPanel,
} from 'react-accessible-accordion';

// Demo styles, see 'Styles' section below for some notes on use.
import 'react-accessible-accordion/dist/fancy-example.css';

export default function Example() {
    return (
        <Accordion>
            <AccordionItem>
                <AccordionItemHeading>
                    <AccordionItemButton>
                        What harsh truths do you prefer to ignore?
                    </AccordionItemButton>
                </AccordionItemHeading>
                <AccordionItemPanel>
                    <p>
                        Exercitation in fugiat est ut ad ea cupidatat ut in
                        cupidatat occaecat ut occaecat consequat est minim minim
                        esse tempor laborum consequat esse adipisicing eu
                        reprehenderit enim.
                    </p>
                </AccordionItemPanel>
            </AccordionItem>
            <AccordionItem>
                <AccordionItemHeading>
                    <AccordionItemButton>
                        Is free will real or just an illusion?
                    </AccordionItemButton>
                </AccordionItemHeading>
                <AccordionItemPanel>
                    <p>
                        In ad velit in ex nostrud dolore cupidatat consectetur
                        ea in ut nostrud velit in irure cillum tempor laboris
                        sed adipisicing eu esse duis nulla non.
                    </p>
                </AccordionItemPanel>
            </AccordionItem>
        </Accordion>
    );
}

Styles

We strongly encourage you to write your own styles for your accordions, but we've published the styles used on our demo page to help you get up and running:

import 'react-accessible-accordion/dist/fancy-example.css';

We recommend that you copy them into your own app and modify them to suit your needs, particularly if you're using your own classNames.

Component API

Accordion

allowMultipleExpanded : boolean [optional, default: false]

Don't autocollapse items when expanding other items.

allowZeroExpanded : boolean [optional, default: false]

Allow the only remaining expanded item to be collapsed.

preExpanded: string[] [optional, default: []]

Accepts an array of strings and any AccordionItem whose uuid prop matches any one of these strings will be expanded on mount.

className : string [optional, default: 'accordion']

Class(es) to apply to element.

onChange : (string[]) => void [optional]

Callback which is invoked when items are expanded or collapsed. Gets passed uuids of the currently expanded AccordionItems.


AccordionItem

className : string [optional, default: accordion__item]

Class(es) to apply to element.

uuid : string|number [optional]

Recommended for use with onChange. Will be auto-generated if not provided.

dangerouslySetExpanded: boolean [optional]

Enables external control of the expansion.

Warning: This may impact accessibility negatively, use at your own risk


AccordionItemHeading

className : string [optional, default: 'accordion__heading']

Class(es) to apply to the 'heading' element.

aria-level : number [optional, default: 3]

Semantics to apply to the 'heading' element. A value of 1 would make your heading element hierarchically equivalent to an <h1> tag, and likewise a value of 6 would make it equivalent to an <h6> tag.

AccordionItemButton

className : string [optional, default: 'accordion__button']

Class(es) to apply to the 'button' element.


AccordionItemPanel

className : string [optional, default: 'accordion__panel']

Class(es) to apply to element.

region: boolean

Make the element have a region role.


AccordionItemState

children : ({ expanded: boolean, disabled: boolean }): JSX.Element [required]


Helpers

resetNextUuid : (): void

Resets the internal counter for Accordion items' identifiers (including id attributes). For use in test suites and isomorphic frameworks.


Accessibility Best-Practice

Authoring an 'accordion' component to the WAI ARIA spec can be complex, but React Accessible Accordion does most of the heavy lifting for you, including:

  • Applying appropriate aria attributes (aria-expanded, aria-controls, aria-disabled, aria-hidden and aria-labelledby).
  • Applying appropriate role attributes (button, heading, region).
  • Applying appropriate tabindex attributes.
  • Applying keyboard interactivity ('space', 'end', 'tab', 'up', 'down', 'home' and 'end' keys).

However, there's still a couple of things you need to keep in mind to remain spec-compliant:

  • Only ever use phrasing content inside of your AccordionItemHeading component. If in doubt, use text only.
  • Always provide an aria-level prop to your AccordionItemHeading component, especially if you are nesting accordions. This attribute is a signal used by assistive technologies (eg. screenreaders) to determine which heading level (ie. h1-h6) to treat your heading as.

If you have any questions about your implementation, then please don't be afraid to get in touch via our issues.

FAQs

React 18?

RAA supports React 18, and the new out-of-order streaming feature. See the CHANGELOG for details.

Which design patterns does this component aim to solve?

Those described by the WAI ARIA spec's description of an 'accordion':

An accordion is a vertically stacked set of interactive headings that each contain a title, content snippet, or thumbnail representing a section of content. The headings function as controls that enable users to reveal or hide their associated sections of content. Accordions are commonly used to reduce the need to scroll when presenting multiple sections of content on a single page.

Which design patterns does this component NOT aim to solve?

Components which are "accordion-like" but do not match the WAI ARIA spec's description, as written above. By "accordion-like", we mean components which have collapsible items but require bespoke interactive mechanisms in order to expand, collapse and 'disable' them. This includes (but is not limited to) multi-step forms, like those seen in many cart/checkout flows, which we believe require (other) complex markup in order to be considered 'accessible'. This also includes disclosure widgets.

How do I disable an item?

See "Which design patterns does this component NOT aim to solve?".

Browser Support

Supported browser / device versions:

BrowserDevice/OSVersion
Mobile SafariiOSlatest
ChromeAndroidlatest
IEWindows11
MS EdgeWindowslatest
ChromeDesktoplatest
FirefoxDesktoplatest
SafariOSXlatest