# Using old React versions URL: /docs/react-compatibility Compatibility notes for React 18, 17, and 16. Older React versions are not continuously tested. If you encounter any issues with integration, please contact us for help by joining our [Discord](https://discord.gg/S9dwgCNEFs). This guide provides instructions for configuring assistant-ui to work with React 18 or older versions. React 18 \[#react-18] If you're using React 18, you need to update the shadcn/ui components to work with `forwardRef`. Specifically, you need to modify the Button component. Updating the Button Component \[#updating-the-button-component] Navigate to your button component file (typically `/components/ui/button.tsx`) and wrap the Button component with `forwardRef`: ```tsx // Before function Button({ className, variant, size, asChild = false, ...props }: React.ComponentProps<"button"> & VariantProps & { asChild?: boolean; }) { const Comp = asChild ? Slot : "button"; return ( ); } // After const Button = React.forwardRef< HTMLButtonElement, React.ComponentProps<"button"> & VariantProps & { asChild?: boolean; } >(({ className, variant, size, asChild = false, ...props }, ref) => { const Comp = asChild ? Slot : "button"; return ( ); }); Button.displayName = "Button"; ``` **Note:** If you're using a lower React version (17 or 16), you'll also need to follow the instructions for that version. React 17 \[#react-17] For React 17 compatibility, in addition to the modifications outlined for React 18, you must also include a polyfill for the `useSyncExternalStore` hook (utilized by zustand). Patching Zustand with patch-package \[#patching-zustand-with-patch-package] Since the assistant-ui uses zustand internally, which depends on `useSyncExternalStore`, you'll need to patch the zustand package directly: 1. Install the required packages: 2. Add a postinstall script to your package.json: ```json { "scripts": { "postinstall": "patch-package" } } ``` 3. You'll want to follow the instructions in [patch-package](https://github.com/ds300/patch-package), by first making changes to the files of a particular package in your node\_modules folder, then running either `yarn patch-package package-name` or `npx patch-package package-name`. You'll need a patch for zustand - within `node_modules/zustand`, open `zustand/react.js` and make the following code changes: ````diff diff --git a/node_modules/zustand/react.js b/node_modules/zustand/react.js index 7599cfb..64530a8 100644 --- a/node_modules/zustand/react.js +++ b/node_modules/zustand/react.js @@ -1,6 +1,6 @@ 'use strict'; -var React = require('react'); +var React = require('use-sync-external-store/shim'); var vanilla = require('zustand/vanilla'); const identity = (arg) => arg; @@ -10,7 +10,7 @@ function useStore(api, selector = identity) { () => selector(api.getState()), () => selector(api.getInitialState()) ); - React.useDebugValue(slice); + //React.useDebugValue(slice); return slice; } const createImpl = (createState) => { This patch replaces the React import in zustand with the polyfill from `use-sync-external-store/shim` and comments out the `useDebugValue` call which isn't needed. You should then run the patch-package command `yarn patch-package zustand` or `npx patch-package zustand` which should create a `patches` folder with a zustand patch file similar looking to this: ```diff diff --git a/node_modules/zustand/react.js b/node_modules/zustand/react.js index 7599cfb..64530a8 100644 --- a/node_modules/zustand/react.js +++ b/node_modules/zustand/react.js @@ -1,6 +1,6 @@ 'use strict'; -var React = require('react'); +var React = require('use-sync-external-store/shim'); var vanilla = require('zustand/vanilla'); const identity = (arg) => arg; @@ -10,7 +10,7 @@ function useStore(api, selector = identity) { () => selector(api.getState()), () => selector(api.getInitialState()) ); - React.useDebugValue(slice); + //React.useDebugValue(slice); return slice; } const createImpl = (createState) => { ```` 4. You may also need to apply the same patches within `node_modules/@assistant-ui/react/` and possibly a nested dependency patch for `node_modules/@assistant-ui/react/node_modules/zustand`. Look for instances of `React.useSyncExternalStore` and replace with `{ useSyncExternalStore } from "use-sync-external-store/shim";` and comment out any `useDebugValue` calls. Finally, you may need to patch `useId` from React, so within `node_modules/@assistant-ui/react/dist/runtimes/remote-thread-list/RemoteThreadListThreadListRuntimeCore.js`, change the following: ```diff -import { Fragment, useEffect, useId } from "react"; +import { Fragment, useEffect, useRef } from "react"; import { create } from "zustand"; import { AssistantMessageStream } from "assistant-stream"; import { RuntimeAdapterProvider } from "../adapters/RuntimeAdapterProvider.js"; import { jsx } from "react/jsx-runtime"; + +// PATCH-PACKAGE: Polyfill for useId if not available in React 16 +let useId; +try { + // Try to use React's useId if available + useId = require("react").useId; +} catch (e) {} +if (!useId) { + // Fallback polyfill + let globalId = 0; + useId = function() { + const idRef = useRef(); + if (!idRef.current) { + globalId++; + idRef.current = `uid-${globalId}`; + } + return idRef.current; + }; +} ``` 5. Run the postinstall script to apply the patches: ```bash npm run postinstall # or yarn postinstall ``` This patch replaces the React import in zustand with the polyfill from `use-sync-external-store/shim` and comments out the `useDebugValue` call which isn't needed. **Note:** If you're using React 16, you'll also need to follow the instructions for that version. React 16 \[#react-16] This section is incomplete and contributions are welcome. If you're using React 16 and have successfully integrated assistant-ui, please consider contributing to this documentation. For React 16 compatibility, you need to apply all the steps for **React 18** and **React 17** above. Additional Resources \[#additional-resources] If you encounter any issues with React compatibility, please: 1. Check that all required dependencies are installed 2. Ensure your component modifications are correctly implemented 3. Join our [Discord](https://discord.gg/S9dwgCNEFs) community for direct support