Framework Adapters
The core runtime is framework agnostic. React has an official adapter; with other frameworks, create the emitter in a client-side lifecycle hook and destroy it on cleanup.
React
@puejs/react binds an emitter to the component lifecycle. It supports React 18 and 19, Strict Mode and the Next.js App Router.
npm install @puejs/core @puejs/react"use client"; import { usePue } from "@puejs/react"; export function Feed({ children }: { children: React.ReactNode }): React.JSX.Element { const { ref, state, start, stop } = usePue<HTMLDivElement>({ preset: "crisp" }); return ( <> <button aria-pressed={state === "running"} onClick={() => (state === "idle" ? start() : stop())} type="button"> Acoustic feedback </button> <div ref={ref} style={{ overflowY: "auto", height: "100vh" }}> {children} </div> </> );}The emitter is created on mount, updated when options change and destroyed on unmount. Without ref, the hook observes window; passing false instead of options disables it. Audio only starts through start() — or usePue(options, { autoStart: true }), which still waits for a user gesture.
Sharing defaults
Wrap your application in PueProvider to share default options and a single AudioContext between every usePue call:
import { PueProvider } from "@puejs/react"; export default function RootLayout({ children }: { children: React.ReactNode }): React.JSX.Element { return ( <html lang="en"> <body> <PueProvider defaults={{ preset: "organic", volume: 0.6 }}>{children}</PueProvider> </body> </html> );}Vue
<script setup lang="ts">import { createEmitter, type Emitter } from "@puejs/core";import { onBeforeUnmount, onMounted, ref } from "vue"; const feed = ref<HTMLElement | null>(null);let emitter: Emitter | null = null;const start = (): void => void emitter?.start(); onMounted(() => { emitter = createEmitter(feed.value!, { preset: "organic" }); window.addEventListener("pointerdown", start, { once: true });});onBeforeUnmount(() => { window.removeEventListener("pointerdown", start); emitter?.destroy();});</script> <template> <section ref="feed" class="feed"><slot /></section></template>Roadmap
Official adapters remove this boilerplate:
| Module | Status |
|---|---|
@puejs/react | Available |
@puejs/vue | Planned |
@puejs/svelte | Planned |
@puejs/solid | Planned |
Follow progress on GitHub.