|
| 1 | +--- |
| 2 | +title: Migrate from react-markdown |
| 3 | +description: Learn how to migrate from react-markdown to Streamdown. |
| 4 | +type: guide |
| 5 | +summary: Migrate from react-markdown to Streamdown. |
| 6 | +prerequisites: |
| 7 | + - /docs/getting-started |
| 8 | +related: |
| 9 | + - /docs/getting-started |
| 10 | + - /docs/configuration |
| 11 | + - /docs/components |
| 12 | + - /docs/styling |
| 13 | +--- |
| 14 | + |
| 15 | +Streamdown is a drop-in replacement for `react-markdown`, designed for AI-powered streaming. It supports all of the same props — `children`, `components`, `remarkPlugins`, `rehypePlugins`, `remarkRehypeOptions`, `allowElement`, `allowedElements`, `disallowedElements`, `skipHtml`, `unwrapDisallowed`, and `urlTransform` — so existing usage works without changes. On top of that, you get built-in syntax highlighting, GFM, math, mermaid diagrams, and prestyled typography. |
| 16 | + |
| 17 | +## AI-assisted migration |
| 18 | + |
| 19 | +You can use the following prompt with an AI coding assistant to automate the migration: |
| 20 | + |
| 21 | +```md title="prompt.md" |
| 22 | +Can you update this repo to use Streamdown instead of React Markdown. |
| 23 | + |
| 24 | +Migration instructions: |
| 25 | + |
| 26 | +- Replace `import ReactMarkdown from "react-markdown"` (or equivalent) with `import { Streamdown } from "streamdown"` |
| 27 | +- If type `Options` is used from react-markdown, create a new type `type Options = ComponentPropsWithoutRef<typeof Streamdown>` |
| 28 | +- If type `Components` is used from react-markdown, create a new type `type Components = ComponentPropsWithoutRef<typeof Streamdown>['components']` |
| 29 | +- If any of the following plugins are used, you can remove them as they're built in to Streamdown: rehype-harden, rehype-katex, rehype-raw, remark-cjk-friendly, remark-cjk-friendly-gfm-strikethrough, remark-gfm, remark-math. However, check that they're not being used elsewhere first. |
| 30 | +- If code blocks or mermaid components exist, you can remove them too as they're built in to Streamdown. This may involve also uninstalling shiki / react-syntax-highlighter from the package.json. |
| 31 | +- If the project is using a tailwind.config file, add the following to the `content` array: `'./node_modules/streamdown/dist/*.js',` (ensuring the node modules path is correct). |
| 32 | +- If the project is using Tailwind 4 globals.css, add the following near the top under imports: `@source "../node_modules/streamdown/dist/*.js";` (ensuring the node modules path is correct). |
| 33 | +- If the old ReactMarkdown component has custom components e.g. p tags, li tags, etc. you can delete them all. These are prestyled in Streamdown. |
| 34 | +- If the old ReactMarkdown component uses `prose` classes, you can remove them too. |
| 35 | +- When updating deps, use the local package manager as defined by the `packageManager` field in package.json or the lockfile e.g. pnpm-lock.yaml = pnpm. |
| 36 | +- When installing Streamdown, use the latest versions of the packages (`streamdown`, `@streamdown/code`, etc.) |
| 37 | +- If the old ReactMarkdown component is memoized / a "MemoizedReactMarkdown" (or equivalent) component exists, remove the memoization. Streamdown does this internally. |
| 38 | +- **Final step: Check if the markdown wrapper file is now redundant. If it just re-exports Streamdown without any custom props, styling, or logic, delete the wrapper file and import Streamdown directly where needed.** |
| 39 | +``` |
| 40 | + |
| 41 | +## What you get |
| 42 | + |
| 43 | +By switching to Streamdown, you can remove a significant amount of boilerplate: |
| 44 | + |
| 45 | +- **100% prop compatibility** — All `react-markdown` props are supported, including `allowElement`, `allowedElements`, `disallowedElements`, `skipHtml`, `unwrapDisallowed`, and `urlTransform`. Types like `Components`, `AllowElement`, `UrlTransform`, and `ExtraProps` are exported directly. |
| 46 | +- **Built-in plugins** — GFM, math (KaTeX), raw HTML, and CJK support are included by default. No need for `remark-gfm`, `remark-math`, `rehype-katex`, `rehype-raw`, `rehype-harden`, `remark-cjk-friendly`, or `remark-cjk-friendly-gfm-strikethrough`. |
| 47 | +- **Code highlighting** — Syntax highlighting with Shiki is built in. You can remove `shiki`, `react-syntax-highlighter`, or any custom code block components. |
| 48 | +- **Mermaid diagrams** — Rendered automatically. No custom mermaid component needed. |
| 49 | +- **Prestyled typography** — All HTML elements are styled out of the box. No `prose` classes or custom component overrides for basic elements like `p`, `li`, `h1`, etc. |
| 50 | +- **Internal memoization** — No need for `MemoizedReactMarkdown` wrappers. |
| 51 | + |
| 52 | +## Step-by-step migration |
| 53 | + |
| 54 | +### 1. Install Streamdown |
| 55 | + |
| 56 | +```package-install |
| 57 | +npm i streamdown |
| 58 | +``` |
| 59 | + |
| 60 | +### 2. Update imports |
| 61 | + |
| 62 | +Replace `react-markdown` imports with Streamdown: |
| 63 | + |
| 64 | +```tsx title="Before" |
| 65 | +import ReactMarkdown from "react-markdown"; |
| 66 | +``` |
| 67 | + |
| 68 | +```tsx title="After" |
| 69 | +import { Streamdown } from "streamdown"; |
| 70 | +``` |
| 71 | + |
| 72 | +Streamdown exports the same types as `react-markdown`, so you can import them directly: |
| 73 | + |
| 74 | +```tsx title="Before" |
| 75 | +import type { Options, Components, ExtraProps } from "react-markdown"; |
| 76 | +``` |
| 77 | + |
| 78 | +```tsx title="After" |
| 79 | +import type { Components, ExtraProps, AllowElement, UrlTransform } from "streamdown"; |
| 80 | +``` |
| 81 | + |
| 82 | +If you need a type for the full Streamdown props, use `StreamdownProps`: |
| 83 | + |
| 84 | +```tsx |
| 85 | +import type { StreamdownProps } from "streamdown"; |
| 86 | +``` |
| 87 | + |
| 88 | +### 3. Remove built-in plugins |
| 89 | + |
| 90 | +If your project uses any of these plugins, you can uninstall them — they're built in to Streamdown: |
| 91 | + |
| 92 | +- `rehype-harden` |
| 93 | +- `rehype-katex` |
| 94 | +- `rehype-raw` |
| 95 | +- `remark-cjk-friendly` |
| 96 | +- `remark-cjk-friendly-gfm-strikethrough` |
| 97 | +- `remark-gfm` |
| 98 | +- `remark-math` |
| 99 | + |
| 100 | +<Callout type="warn"> |
| 101 | + Check that these plugins aren't used elsewhere in your project before removing them. |
| 102 | +</Callout> |
| 103 | + |
| 104 | +### 4. Remove code block and mermaid components |
| 105 | + |
| 106 | +Custom code block or mermaid diagram components can be deleted — Streamdown handles these natively. This may also allow you to uninstall `shiki` or `react-syntax-highlighter` from your `package.json`. |
| 107 | + |
| 108 | +### 5. Remove custom component overrides |
| 109 | + |
| 110 | +If the old `ReactMarkdown` component has custom component overrides for basic elements (e.g. `p`, `li`, `h1`), you can delete them. Streamdown prestyles all standard HTML elements. |
| 111 | + |
| 112 | +Similarly, if the wrapper uses `prose` Tailwind classes, you can remove those too. |
| 113 | + |
| 114 | +### 6. Remove memoization |
| 115 | + |
| 116 | +If a `MemoizedReactMarkdown` (or equivalent) wrapper exists, remove it. Streamdown handles memoization internally. |
| 117 | + |
| 118 | +### 7. Configure Tailwind CSS |
| 119 | + |
| 120 | +Streamdown uses Tailwind CSS for styling. Add the source path so Tailwind picks up the classes: |
| 121 | + |
| 122 | +**Tailwind v4** — add to your `globals.css`: |
| 123 | + |
| 124 | +```css title="globals.css" |
| 125 | +@source "../node_modules/streamdown/dist/*.js"; |
| 126 | +``` |
| 127 | + |
| 128 | +**Tailwind v3** — add to your `tailwind.config.js`: |
| 129 | + |
| 130 | +```js title="tailwind.config.js" |
| 131 | +module.exports = { |
| 132 | + content: [ |
| 133 | + // ... your existing paths |
| 134 | + "./node_modules/streamdown/dist/*.js", |
| 135 | + ], |
| 136 | +}; |
| 137 | +``` |
| 138 | + |
| 139 | +Adjust the `node_modules` path based on your project structure. See [Tailwind CSS Configuration](/docs/getting-started#tailwind-css-configuration) for monorepo setups. |
| 140 | + |
| 141 | +### 8. Clean up |
| 142 | + |
| 143 | +Check if your markdown wrapper file is now redundant. If it just re-exports Streamdown without any custom props, styling, or logic, delete the wrapper and import Streamdown directly where needed. |
0 commit comments