Frameworks
Optional React and Vue wrappers generate accessible markup (structure, IDs, ARIA). Import the core runtime once; wrappers contain no state, effects, or event handlers. All interactivity comes from the monochrome runtime.
You can write the same HTML by hand or with any templating layer. See Installation if you have not added the package yet.
Peer versions
Declared peers in the monochrome package:
| Peer | Requirement |
|---|---|
react / react-dom |
>=18 |
vue |
>=3.5 |
Both are optional: you only need the peer for the wrapper entry you import.
Setup
Import the runtime in your app entry or root layout:
import "monochrome"Then import components from @monochrome-ui/react or @monochrome-ui/vue where you need them.
React
import "monochrome"
import { Accordion } from "@monochrome-ui/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>
)
}Vue
<script setup lang="ts">
import "monochrome"
import { Accordion } from "@monochrome-ui/vue"
</script>
<template>
<Accordion.Root>
<Accordion.Item>
<Accordion.Header>
<Accordion.Trigger>Is Vue required?</Accordion.Trigger>
</Accordion.Header>
<Accordion.Panel>
No. Vue is one way to generate the HTML.
</Accordion.Panel>
</Accordion.Item>
</Accordion.Root>
</template>Both produce the same HTML contract the core expects. The runtime handles clicks, keyboard, and focus.
Compatible Stacks
Wrappers work anywhere React or Vue renders HTML:
- React: Next.js, Remix, Astro (React islands), Vite SPAs
- Vue: Nuxt, Astro (Vue islands), Vite + Vue, plain Vue SSR
Because the wrappers are pure markup generators, server-rendered setups can ship zero framework client JavaScript for these components. The monochrome runtime is the only script needed in the browser for interactivity.
Why Use Wrappers?
| Without wrappers | With wrappers |
|---|---|
Write mct:, mcc:, mcr: IDs by hand |
IDs generated automatically |
Set aria-expanded, aria-hidden, role, hidden |
Attributes set by the component |
Match aria-controls to content IDs |
Wired up internally |
| Remember the correct element structure | Enforced by the component tree |
The output is identical. Wrappers are a convenience layer, not a second runtime.
Next Steps
- Accordion, Collapsible, and other reference pages for props and structure
- Architecture for why the runtime does not need framework state