View as Markdownllms.txt

Dependency & Compatibility Guide

For client apps integrating @revrag-ai/embed-react · SDK 1.5.0

Which React, framework, router, bundler and TypeScript versions the web SDK works with, what the SDK installs into the host app, and what to do when the host is outside the supported ranges.

Everything here comes from the package's package.json, its build config and the example apps in the SDK repository (examples/*).

StatusMeaning
ExercisedAn example app in the SDK repository builds and runs on that stack
In rangeThe peer ranges allow it, but no example covers it

Treat "exercised" as strong evidence, not a release certification.

The examples build against the SDK's source through bundler aliases, not the published tarball.


Table of contents

  1. Known-good stacks — pick one, and pick the right entry
  2. Peer dependencies
  3. What the SDK installs into the host
  4. Frameworks, routers and bundlers
  5. Outside the ranges: workarounds
  6. TypeScript
  7. Browsers and runtime
  8. Package managers
  9. Out of scope

1. Known-good stacks

Pin to one of these when you can. Each row is an example app in the SDK repository.

StackReactFramework / bundlerRouterTypeScriptSDK entryExample
A. React 19 SPAreact/react-dom 19.2.xVite 7.3 + @vitejs/plugin-react 5.1react-router-dom 7.x (7.13.1)5.9 (bundler)defaultexamples/react
B. Next.js App Router19.2.3Next.js 16.1.6Next (App Router)5.x (bundler)defaultexamples/nextjs
C. React 17 SPA17.0.2Vite 7.3none / any—default (works on Vite)examples/react17-smoke
D. React 17 + Next.js17.0.2Next.js 12.3.4 (webpack 5)Next (Pages Router)4.9.5 (node + paths)/react17examples/next17-smoke
E. Preactpreact 10.29.x via preact/compatVite 7.3 + @preact/preset-vite 2.10preact-router 4.1.2(bundler)defaultexamples/preact-poc

Pick the entry by the host's React version and bundler:

HostEntry to import from
React 18 / 19, any bundler@revrag-ai/embed-react
React 17 on Vite (Rollup)@revrag-ai/embed-react
React 17 on webpack (CRA, Next.js 12, custom webpack)@revrag-ai/embed-react/react17
Preact 10 (Vite preset, or webpack with aliases)@revrag-ai/embed-react

Why webpack + React 17 needs its own entry.

  • The default entry imports framer-motion 12, which statically imports useId / useInsertionEffect from react. Those hooks only exist in React 18+.
  • Webpack checks named imports at build time and fails with Attempted import error; Rollup/Vite only warns.
  • The /react17 entry is the same code with framer-motion swapped for a built-in stub, so it never touches those imports.

2. Peer dependencies

PackageDeclared rangeRequiredStatus
react>=17.0.0yes17 (A/C/D), 19 (A/B) exercised; 18 in range
react-dom>=17.0.0yessame as react; must be the same version
next>=14.0.0optional16 exercised; 14, 15 in range; 12 exercised but out of range (see §5)
react-router-dom>=6.0.0optional7 exercised; 6 in range; 5 out of range (see §5)
  • next and react-router-dom are optional peers. The published bundles never import either one: the host passes the current path to EmbedProvider as a string.
  • Any router works, including ones not listed (TanStack Router, preact-iso, wouter, a hand-rolled state machine).

3. What the SDK installs into the host

These are runtime dependencies of @revrag-ai/embed-react, so npm installs them into the host.

Do not add any of them to the host's package.json for the SDK.

PackageRangeUsed byIf the host already has it
livekit-client^2.6.0voice calls. Loaded with a dynamic import() only when a call startsHost on 2.x ⇒ npm shares one copy (fine). Host on 1.x ⇒ the SDK gets its own nested 2.x copy (fine, larger install)
framer-motion^12.23.9widget animations. Default entry only; the /react17 entry never imports itHost on 12.x ⇒ shared. Host on ≤ 11 ⇒ a second nested copy, which costs bundle size but doesn't conflict. Host using the motion package ⇒ separate, no conflict
zustand^4.5.5internal stateHost on zustand 5 ⇒ nested copy, independent stores, no conflict
zod^3.24.1validating backend/agent messagesHost on zod 4 ⇒ nested copy, no conflict
zod-to-json-schema^3.23.5schema helpers—
clsx^2.1.1class names—
tailwind-merge^2.5.4class namesHost on 3.x ⇒ nested copy, no conflict
tailwindcss-animate^1.0.7listed, build-time onlyThe host does not need Tailwind
tiny-invariant^1.3.3assertions—

Bundled inside the package (not installed, cannot conflict):

  • @revrag-ai/embed-core — shipped in internal/core. Never install or import it.
  • lottie-web (5.13) — bundled into its own chunk (lottie-*.js, ~420 KB).
    • The chunk is split out, but the default avatar animation itself is in the main bundle, so expect a noticeable first-load cost.
    • A host's own lottie-web / lottie-react is unaffected.

Stylesheet. @revrag-ai/embed-react/style.css (~32 KB) is precompiled.

  • Every rule is scoped to the widget's own embed-* / ai-widget-* classes; there is no global reset.
  • It works with or without Tailwind, CSS Modules, styled-components, Emotion or MUI in the host.

Check the result after installing:

npm ls @revrag-ai/embed-react      # 1.5.0
npm ls react react-dom             # exactly ONE copy each
npm ls livekit-client --all        # one 2.x copy is ideal; a nested second copy is acceptable
npm ls framer-motion --all         # default entry only

Two copies of react / react-dom are never acceptable. They give Invalid hook call.

  • This usually happens in monorepos, with linked packages, or with pnpm hoisting.
  • Dedupe them: npm dedupe, resolutions / overrides, or a bundler alias to the app's copy.

4. Frameworks, routers and bundlers

React

VersionStatusNotes
19.xexercised (A, B)
18.xin rangeSame code path as 19
17.xexercised (C, D)useSyncExternalStore is polyfilled internally; animations are simpler (static styles instead of motion), which is expected. Add no polyfills. Webpack hosts must use /react17
≤ 16unsupportedHooks-only SDK; peer range excludes it

Next.js

VersionRouterStatusNotes
16App Routerexercised (B)The package ships "use client"; useInitialize / usePathname still go in one client component
14, 15App / Pagesin rangeSame integration as 16
13App / Pagesout of peer rangeInstall with --legacy-peer-deps. The SDK never imports next, so this is safe
12Pagesexercised (D), out of peer rangeReact 17 ⇒ /react17 entry; --legacy-peer-deps
≤ 11—untestedwebpack 4 era; not supported

For the Pages Router, pass router.pathname (the route pattern), never router.asPath.

Routers

RouterStatusWhat to pass as currentPath
react-router-dom 7exercised (A)useLocation().pathname
react-router-dom 6in rangeuseLocation().pathname
react-router-dom 5out of peer range (--legacy-peer-deps); the SDK doesn't import ituseLocation().pathname / withRouter location.pathname
Next.js App Routerexercised (B)usePathname()
Next.js Pages Routerexercised (D)useRouter().pathname
preact-router 4exercised (E)current URL's pathname
preact-isoin rangeuseLocation().path (inside <LocationProvider>)
TanStack Router, wouter, othersworks through the propthe router's current pathname
No routerworks through the propa synthetic path per screen, e.g. /onboarding/${step}

Bundlers

BundlerStatusNotes
Vite 7exercised (A, C, E)
Vite 5–6in range
webpack 5 (Next.js 12+)exercised (D)React 17 ⇒ /react17
webpack 5 (CRA react-scripts 5, custom)in rangeReact 17 ⇒ /react17
Turbopack (Next.js 15/16 dev)in range
Rspack, Parcel, esbuilduntestedShould work: plain ESM + CJS, standard exports map. Report issues
webpack 4unsupportedDoesn't understand the package exports map

The package publishes both ESM (index.js) and CJS (index.cjs) behind an exports map.

Any bundler that ignores exports can't resolve /react17, /diagnostics or /style.css.

Preact

preact 10 through preact/compat.

  • Vite + @preact/preset-vite: nothing to configure.
  • webpack: alias react, react-dom, react-dom/test-utils and react/jsx-runtime to preact/compat / preact/test-utils / preact/jsx-runtime.
  • npm may install react / react-dom to satisfy the peers. With the aliases in place they never reach the bundle.

5. Outside the ranges: workarounds

HostSymptomDo
Next.js 12 or 13npm ERR! ERESOLVE on installnpm install --legacy-peer-deps (or an overrides entry). Safe: the SDK never imports next
React Router 5same ERESOLVEsame workaround
React 17 on webpack, default entryAttempted import error: 'useId' is not exported from 'react' (from framer-motion)Import everything from @revrag-ai/embed-react/react17
TS moduleResolution: "node"Cannot find module '@revrag-ai/embed-react/react17' (or /diagnostics)Switch to bundler / nodenext, or add compilerOptions.paths (below)
Two React copiesInvalid hook callDedupe (see §3)
yarn berry with PnPresolution errors in SDK dependenciesnodeLinker: node-modules in .yarnrc.yml
pnpm strict-peer-dependenciesinstall fails on optional peersLeave it off, or use peerDependencyRules.allowedVersions

The compilerOptions.paths entries for moduleResolution: "node":

{
  "compilerOptions": {
    "paths": {
      "@revrag-ai/embed-react/react17": ["./node_modules/@revrag-ai/embed-react/index.d.ts"],
      "@revrag-ai/embed-react/diagnostics": ["./node_modules/@revrag-ai/embed-react/diagnostics.d.ts"]
    }
  }
}

Do not up- or downgrade the host's unrelated dependencies to fit the SDK.

Every mismatch above has a workaround that leaves the host's versions alone.


6. TypeScript

Versions4.9 (D) and 5.x (A, B) exercised
moduleResolutionbundler or nodenext recommended. node (node10) needs the paths entries in §5 for subpaths
TypesBundled (index.d.ts, diagnostics.d.ts). No @types package to install
@types/reactUse the one that matches the host's React (17.x types for React 17). The SDK doesn't force one

7. Browsers and runtime

RequirementDetail
JavaScriptES2020 output (Vite's default library target: Chrome 87, Edge 88, Firefox 78, Safari 14). Older browsers need the host to transpile node_modules, and are untested
CallsWebRTC + getUserMedia, in a secure context (HTTPS, or localhost)
StoragesessionStorage is required: the widget doesn't render without it. localStorage is optional. IndexedDB is optional (falls back to memory)
Test onDesktop Chrome and iOS Safari, on the production build. iOS Safari only allows the mic and audio after a user gesture
SSRSafe to import on the server: nothing touches window at import. Hooks must run in client components

8. Package managers

ManagerNotes
npm 7+Installs peers automatically. Expect ERESOLVE only in the §5 cases
yarn classicDoesn't install peers: make sure react / react-dom are present (they are in any React app)
yarn berryUse nodeLinker: node-modules
pnpmWorks; check pnpm why react for a single copy in workspaces

9. Out of scope

  • Angular has its own package, @revrag-ai/embed-angular — see the Angular integration guide.
  • Vue isn't supported by this package.
  • React Native has its own package, @revrag-ai/embed-react-native — see the React Native integration guide.
  • Plain <script> / CDN usage without a bundler is untested.

Setup code: React integration guide.


Support