Get Started

React

React components that render accessible HTML. No client-side React required.

React is completely optional. monochrome works with plain HTML and any backend. The React components are a convenience layer for generating the correct semantic markup.

How It Works

The React components in monochrome/react are HTML templates. They generate the correct element structure, IDs, and ARIA attributes that monochrome needs. They contain no state, no effects, no event handlers, and no client-side logic.

All interactivity comes from the monochrome runtime, a standalone 2.2kB (2219B) script that uses event delegation on the DOM. It works the same whether the HTML was rendered by React in a client-side SPA, on the server, or written by hand.

import "monochrome"
import { Accordion } from "monochrome/react"

export function FAQ() {
  return (
    <Accordion.Root>
      <Accordion.Item>
        <Accordion.Header>
          <Accordion.Trigger>Is React required?</Accordion.Trigger>
        </Accordion.Header>
        <Accordion.Panel>
          No. React is one way to generate the HTML.
        </Accordion.Panel>
      </Accordion.Item>
    </Accordion.Root>
  )
}

This renders the following HTML. The monochrome runtime handles the rest.

<div id="mcr:accordion:r1" data-mode="single">
  <div>
    <h3>
      <button id="mct:accordion:r1" aria-expanded="false" aria-controls="mcc:accordion:r1">
        Is React required?
      </button>
    </h3>
    <div id="mcc:accordion:r1" role="region" aria-labelledby="mct:accordion:r1" aria-hidden="true" hidden="until-found">
      No. React is one way to generate the HTML.
    </div>
  </div>
</div>

Any React Setup

The components work with any React project. Client-side SPAs, server-rendered apps, static sites. Wherever React renders HTML, monochrome picks it up.

  • Vite, Create React App, or any SPA: Components render in the browser, monochrome activates immediately
  • Next.js: Works in Server Components, Client Components, and Pages Router
  • Remix: Server or client rendering, both work
  • Astro: React components in .astro files with no client: directive

Because the components are pure HTML output, server-rendered setups can ship no React JavaScript to the client at all. The monochrome runtime is the only script needed in the browser. But this is a bonus, not a requirement.

Why React Components?

Writing the HTML by hand works perfectly, but the React components save you from managing IDs and ARIA attributes manually:

Without ReactWith React
Write mct:, mcc:, mcr: IDs by handIDs generated automatically
Set aria-expanded, aria-hidden, role, hiddenAttributes set by the component
Match aria-controls to content IDsWired up internally
Remember the correct element structureEnforced by the component tree

The output is identical. The components are a convenience layer, not a runtime dependency.

Setup

Install monochrome and import both the runtime and the React components:

// App entry point or layout
import "monochrome"
// Any component file
import { Menu } from "monochrome/react"

The runtime import registers event listeners once. The React imports are used wherever you need components. Both are fully typed with TypeScript definitions included.

Next Steps