remar-stream
v0.1.2
Published
Streaming Markdown renderer for AI chat — supports KaTeX math, Mermaid diagrams, code highlighting, and plugin extension
Downloads
321
Maintainers
Readme
Remar-stream · React 流式 Markdown 渲染组件
专为 AI 聊天界面设计的 React Markdown 流式渲染组件,原生支持 SSE 流式更新、KaTeX 数学公式与 Mermaid 图表。基于 useDeferredValue、useTransition 等 React 18/19 并发特性,在流式输入场景下保持渲染稳定与流畅。
特性
- 单树架构 — 流式和静态使用同一套 block 渲染管线,流式结束时 block 自然 settled。
- 字符级淡入动画 —
rehypeStreamAnimated插件为文本字符注入animation-delay,CSS 驱动逐字淡入 - 块级时间线动画 —
useBlockAnimationhook 管理 block 状态(queued → animating → revealed),RAF 时间线驱动 - 流式内容平滑 —
useSmoothStreamContenthook 动态调整字符输出速率(CPS),自动闭合不完整 Markdown 语法 - React 并发优化 —
useDeferredValue降低流式更新优先级,useTransition批量更新 block 状态 - 数学公式 — KaTeX 渲染,支持行内(
$...$)和块级($$...$$),LRU 缓存加速 - Mermaid 图表 — 懒加载 Mermaid 模块(主包减负约 500KB),内置缩放/下载/全屏/源码工具栏,SVG 缓存 + 防抖
- 代码高亮 — PrismJS,内置 14 种常用语言,代码块显示语言标签和复制按钮
- 插件系统 — 内置
PluginRegistry注册中心,支持扩展自定义 Markdown 元素渲染 - TypeScript — 完整类型定义,开箱即用
安装
npm install remar-stream
# 或
yarn add remar-stream
# 或
pnpm add remar-streamPeer dependencies(需在项目中安装):
npm install react@^18.0.0 react-dom@^18.0.0
# 或 React 19
npm install react@^19.0.0 react-dom@^19.0.0快速上手
静态内容
import { RemarMarkdown } from 'remar-stream';
function App() {
return <RemarMarkdown content="# Hello, remar!" />;
}SSE 流式场景
import { useState } from 'react';
import { RemarMarkdown } from 'remar-stream';
function ChatMessage() {
const [content, setContent] = useState('');
const [isStreaming, setIsStreaming] = useState(false);
const sendMessage = async (message: string) => {
setIsStreaming(true);
setContent('');
const response = await fetch('/api/chat', {
method: 'POST',
body: JSON.stringify({ message }),
});
const reader = response.body?.getReader();
const decoder = new TextDecoder();
while (reader) {
const { done, value } = await reader.read();
if (done) break;
setContent(prev => prev + decoder.decode(value));
}
setIsStreaming(false);
};
return <RemarMarkdown content={content} isStreaming={isStreaming} />;
}无动画模式
不需要动画时(配合外部滚动、追求极致性能),传入 disableAnimation 跳过所有字符/块级动画:
<RemarMarkdown
content={content}
isStreaming={isStreaming}
disableAnimation
/>暗色主题
通过 theme prop 切换暗色模式,组件自动设置 data-theme="dark" 属性:
<RemarMarkdown content={content} theme="dark" />自定义 Mermaid 渲染
通过插件系统自定义 Mermaid 渲染行为(主题、缓存等):
import { getRegistry, mermaidPlugin } from 'remar-stream';
const registry = getRegistry();
await registry.register(mermaidPlugin({ theme: 'dark', cacheMaxSize: 100 }));完整插件系统文档请参阅 docs/plugin-system.zh-CN.md
API
<RemarMarkdown>
| Prop | 类型 | 默认值 | 说明 |
| -------------------- | -------------------------------- | --------- | ------------------------- |
| content | string | 必填 | Markdown 字符串 |
| isStreaming | boolean | false | 启用流式优化模式 |
| className | string | — | 附加到容器的 CSS 类名 |
| theme | 'light' \| 'dark' | 'light' | 主题模式,通过 data-theme 属性切换 |
| disableAnimation | boolean | false | 跳过所有动画以优化性能 |
| viewportBlockRange | { start: number; end: number } | — | 视口 block 范围,用于懒渲染 |
支持的 Markdown 语法
基于 react-markdown + remark-gfm,支持标准 CommonMark 和 GFM 扩展语法,包括标题、粗体、斜体、列表、链接、图片、代码块、引用、分隔线、表格、任务列表。
数学公式(KaTeX)
行内:$E = mc^2$
块级:
$$
\sum_{i=1}^{n} x_i = x_1 + x_2 + \cdots + x_n
$$Mermaid 图表
```mermaid
graph TD
A[开始] --> B{判断}
B -->|是| C[确定]
B -->|否| D[结束]
```代码高亮(PrismJS)
内置支持:JavaScript、TypeScript、JSX、TSX、Python、Go、Bash、JSON、CSS、SQL、YAML、Markdown、Rust、Java 共 14 种语言。
主题定制
remar 的样式基于三层 Design Token 体系(Seed → Map → Dark),支持通过 CSS 变量自定义外观,暗色模式开箱即用。
完整主题定制文档请参阅 docs/theme.zh-CN.md
常见问题
流式输出时动画效果是怎样的?
remar 的动画分为两层:
- 字符级:
rehypeStreamAnimated插件为块级元素(p、h1-h6 等)内的文本字符逐个包裹<span class="stream-char">,通过 CSSanimation-delay实现依次淡入。代码块、表格、KaTeX 元素内的字符不参与字符级动画。 - 块级:
useBlockAnimationhook 管理queued → animating → revealed状态机,所有块并行启动,基于 RAF 时间线驱动。
disableAnimation 模式下会跳过所有动画,block 直接以 settled 状态渲染。
支持 Next.js 吗?
支持。remar 的构建产物已内置 "use client" 指令,无需手动添加。在 App Router 中直接导入即可:
import { RemarMarkdown } from 'remar-stream';不使用流式场景时可以用吗?
可以。省略 isStreaming prop 或设为 false,remar 即作为普通静态 Markdown 渲染器使用,无动画开销。
需要手动引入 CSS 吗?
通常不需要。dist/index.js 顶部包含 CSS 静态引用,Vite / Webpack / Next.js 等构建工具会自动处理。只需正常导入组件即可:
import { RemarMarkdown } from 'remar-stream';如果样式未生效(非标准打包环境),可手动引入:
import 'remar-stream/styles.css';依赖了哪些 UI 组件库?
不依赖任何 UI 组件库。remar 的 peer dependencies 只有 react(^18.0.0 || ^19.0.0)和 react-dom,可以与 Ant Design、MUI、Arco Design、shadcn/ui 等任何 UI 框架共存。样式基于 CSS 变量体系,通过 --remar- 前缀隔离,不会污染全局样式。
如何扩展自定义渲染?
remar 提供插件系统,支持注册自定义组件匹配规则、remark 插件、语言映射等。详见 插件系统文档。
参与贡献
欢迎提交 Issue 和 Pull Request。
开源协议
License
MIT © remar
