<!-- GENERATED by scripts/build-llms.mjs from package.json + src/components/ — do not edit this file. -->

# Optional peer dependencies

All 29 peers are **optional**: nothing here is needed to install or use the library,
but they have two deliberately different roles.

**Framework declaration peers (3).** React, Svelte, and Vue are compile-time peers
only when a project imports their matching opt-in declaration entry. Those entry points emit empty
JavaScript, no component imports these frameworks, and Lyra ships no runtime wrapper.

**Component-loaded peers (26).** No component imports one eagerly. Install a
peer only when you use a component that needs it.

**How they load.** Most component-loaded peers resolve through a dynamic `import()` on first use.
Loading and failure behavior is component-specific: placeholders, `aria-busy`, visible localized
fallbacks, events, and console diagnostics vary. Consult the owning component section for its exact
loading and failure contract. `<lr-phone-input>` is the exception: it takes an explicit
consumer-built adapter
(`loadLibphonenumberAdapter()`) instead of importing `libphonenumber-js` itself.

**SheetJS (`xlsx`).** The supported `>=0.20.3 <0.21.0` releases are distributed by SheetJS
from its CDN, not the public npm registry (whose newest release is 0.18.5). Install the peer
with `pnpm add https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz` (or the equivalent npm
command), matching the range below. The npm-published 0.18.5 release has unresolved advisories;
do not run `npm audit fix --force` to address them when it proposes downgrading lyra-ui. That
changes the component library version without installing a supported SheetJS release.

**PDF.js (`pdfjs-dist`).** Installing the peer is not sufficient on its own: PDF.js renders in a
web worker, and it has no way to locate that worker inside a bundled app. If nothing configures
it, every document load rejects with `No "GlobalWorkerOptions.workerSrc" specified.` Point
`<lr-pdf-viewer>` at the worker chunk your own bundler emitted, either per element with
`worker-src` (`<lr-pdf-viewer worker-src="/assets/pdf.worker.mjs">`) or once at startup by
importing `pdfjs-dist` yourself and setting `GlobalWorkerOptions.workerSrc`. An already-configured
global always wins, and because that global is process-wide the first viewer to load settles it
for the page.

| Peer | Range | Needed by |
|---|---|---|
| `@aceshooting/lyra-flags` | `^2.3.0` | _(loaded by a shared internal module)_ |
| `@aiden0z/pptx-renderer` | `^1.3.0` | `lr-pptx-viewer` |
| `@sgratzl/chartjs-chart-boxplot` | `^4.0.0` | `lr-box-plot` |
| `chart.js` | `^4.0.1` | `lr-bar-chart`, `lr-box-plot`, `lr-bubble-chart`, `lr-chart`, `lr-doughnut-chart`, `lr-histogram`, `lr-line-chart`, `lr-pie-chart`, `lr-polar-area-chart`, `lr-radar-chart`, `lr-scatter-chart` |
| `chartjs-plugin-annotation` | `^3.0.0` | `lr-bar-chart`, `lr-bubble-chart`, `lr-chart`, `lr-doughnut-chart`, `lr-histogram`, `lr-line-chart`, `lr-pie-chart`, `lr-polar-area-chart`, `lr-radar-chart`, `lr-scatter-chart` |
| `chartjs-plugin-datalabels` | `^2.2.0` | `lr-bar-chart`, `lr-bubble-chart`, `lr-chart`, `lr-doughnut-chart`, `lr-histogram`, `lr-line-chart`, `lr-pie-chart`, `lr-polar-area-chart`, `lr-radar-chart`, `lr-scatter-chart` |
| `chartjs-plugin-zoom` | `^2.0.0` | `lr-bar-chart`, `lr-bubble-chart`, `lr-chart`, `lr-doughnut-chart`, `lr-histogram`, `lr-line-chart`, `lr-pie-chart`, `lr-polar-area-chart`, `lr-radar-chart`, `lr-scatter-chart` |
| `d3-drag` | `^3.0.0` | `lr-graph`, `lr-knowledge-graph-explorer` |
| `d3-force` | `^3.0.0` | `lr-graph`, `lr-knowledge-graph-explorer` |
| `d3-selection` | `^3.0.0` | `lr-graph`, `lr-knowledge-graph-explorer` |
| `d3-zoom` | `^3.0.0` | `lr-graph`, `lr-knowledge-graph-explorer` |
| `dompurify` | `^3.4.14` | `lr-agent-workspace`, `lr-dashboard-grid`, `lr-docx-viewer`, `lr-email-viewer`, `lr-eval-run`, `lr-html-viewer`, `lr-icon`, `lr-icon-button`, `lr-include`, `lr-markdown`, `lr-markdown-core`, `lr-message-parts`, `lr-notebook-viewer`, `lr-rag-answer`, `lr-streaming-text`, `lr-streaming-text-core`, `lr-svg-viewer`, `lr-video`, `lr-video-playlist`, `lr-widget-renderer` |
| `emoji-picker-element-data` | `^1.8.0` | `lr-emoji-picker` |
| `epubjs` | `^0.3.93` | `lr-ebook-viewer` |
| `ical.js` | `^2.2.1` | `lr-calendar-viewer` |
| `katex` | `^0.18.4` | `lr-agent-workspace`, `lr-dashboard-grid`, `lr-eval-run`, `lr-markdown`, `lr-markdown-core`, `lr-message-parts`, `lr-notebook-viewer`, `lr-rag-answer`, `lr-streaming-text`, `lr-streaming-text-core`, `lr-widget-renderer` |
| `libphonenumber-js` | `>=1.11.0 <2` | _(not referenced by any component)_ |
| `mammoth` | `^1.12.1` | `lr-docx-viewer` |
| `maplibre-gl` | `>=5 <7` | `lr-geojson-view`, `lr-geojson-viewer`, `lr-map` |
| `marked` | `^18.0.11` | `lr-agent-workspace`, `lr-dashboard-grid`, `lr-eval-run`, `lr-markdown`, `lr-markdown-core`, `lr-message-parts`, `lr-notebook-viewer`, `lr-rag-answer`, `lr-streaming-text`, `lr-streaming-text-core`, `lr-widget-renderer` |
| `papaparse` | `^5.7.0` | `lr-csv-viewer`, `lr-dataset-viewer` |
| `pdfjs-dist` | `^6.3.289` | `lr-pdf-viewer` |
| `postal-mime` | `^3.0.0` | `lr-email-viewer` |
| `qrcode` | `^1.5.4` | `lr-qr-code` |
| `react` | `>=19 <20` | type-only `@aceshooting/lyra-ui/custom-elements-jsx` entry (no runtime import) |
| `shiki` | `^4.4.3` | `lr-agent-workspace`, `lr-code-block`, `lr-code-block-core`, `lr-dashboard-grid`, `lr-diff-view`, `lr-document-compare`, `lr-eval-result`, `lr-eval-run`, `lr-markdown`, `lr-markdown-core`, `lr-message-parts`, `lr-notebook-viewer`, `lr-rag-answer`, `lr-streaming-text`, `lr-streaming-text-core`, `lr-widget-renderer` |
| `svelte` | `>=5 <6` | type-only `@aceshooting/lyra-ui/svelte` entry (no runtime import) |
| `vue` | `>=3.5 <4` | type-only `@aceshooting/lyra-ui/vue` entry (no runtime import) |
| `xlsx` | `>=0.20.3 <0.21.0` | `lr-spreadsheet-viewer` |
