tldraw SDK 实践指南:在 React 中构建无限画布应用的完整路线
tldraw 是一个功能完备的无限画布引擎,目标是作为任意画布类应用(白板、协作、可视化编程、AI 绘图等)的基础设施。本文基于仓库根目录的 README.md 展开:先完整继承其中的功能特性、快速上手、Starter kits、本地开发与文档指引,再结合 packages/ 下的源码,解释 <Tldraw /> 组件内部如何合并默认形状、工具与 UI,帮助你在“能跑起来”的基础上理解“为什么这样设计”,从而快速掌握 tldraw SDK 的使用与二次扩展能力。
一、tldraw 是什么:功能全景
README 对 tldraw 的定位是:为任何画布应用提供基础能力的、功能完备的无限画布引擎。你可以直接使用它内置的白板工具集,也可以利用库提供的原语(primitives)完全自定义形状、工具与交互。官方列举的核心能力如下(均继承自 README.md 的 Feature highlights 一节):
- Multiplayer(多人协作):基于
@tldraw/sync的、可自托管的实时协作; - Drawing and diagramming(绘图与图表):压感笔绘制、几何形状、富文本、箭头、吸附到形状、边缘滚动(edge scrolling)、图片与视频支持、图片导出;
- Runtime API(运行时 API):通过 Editor API 在运行时驱动画布(读/写内容、切换工具、监听事件等);
- Fully extensible(完全可扩展):自定义 shapes、tools、bindings、UI components、side effects(副作用)以及事件钩子(event hooks);
- AI integrations(AI 集成):提供用于“与 LLM 一起构建画布应用”的画布原语;
- DOM canvas(DOM 画布渲染):基于 DOM 而非位图 canvas 渲染,因此画布内可以呈现浏览器支持的一切内容,包括来自 YouTube、Figma、GitHub 等的嵌入式网站(embed shape);
- Broad support(广泛支持):跨浏览器工作,覆盖桌面、触摸屏、平板与移动设备。
README 的 “Who's using tldraw” 一节列出了大量生产环境使用者:Google、Shopify、BlackRock、Autodesk(Forma)、ClickUp、Replit、Luma、Runway、Padlet、Mobbin、Craft、Honeycomb 等。这说明该 SDK 的公开 API 与协作栈(sync)已经过较多真实产品场景的检验。
二、快速上手:一个组件装进无限画布
2.1 安装与最小示例
按照 README.md 的 Quick start 一节,接入只需要两步。第一步,安装 tldraw 包:
npm i tldraw
第二步,在 React 应用中使用 <Tldraw /> 组件并引入样式文件:
import { Tldraw } from 'tldraw'
import 'tldraw/tldraw.css'
export default function App() {
return (
<div style={{ position: 'fixed', inset: 0 }}>
<Tldraw />
</div>
)
}
两个细节值得注意:
- 样式必须显式引入:
tldraw/tldraw.css需要单独 import,这是包的files字段里随包发布的资源(见 packages/tldraw/package.json); - 外层容器需要占满空间:示例中用
position: fixed; inset: 0的容器包裹,是因为画布组件会撑满其父级容器。
<Tldraw /> 组件对外导出的类型是 TldrawProps = TldrawBaseProps & TldrawEditorStoreProps(见 Tldraw.tsx),也就是说它同时接受“UI/覆盖类属性”(如 components、assetUrls、locale、hideUi)与“编辑器/存储类属性”(如 persisting、onMount、shapeUtils、tools 等),这是后面理解扩展点的基础。
2.2 源码视角:<Tldraw /> 做了哪些“合并默认值”
阅读 Tldraw.tsx 可以清楚看到,这个“一个组件搞定一切”的封装,本质上是把用户传入的扩展项与 SDK 内置的默认项按类型做合并:
// packages/tldraw/src/lib/Tldraw.tsx(节选)
const shapeUtilsWithDefaults = useMemo(
() => mergeArraysAndReplaceDefaults('type', _shapeUtils, defaultShapeUtils),
[_shapeUtils]
)
shapeUtils、bindingUtils、assetUtils、overlayUtils分别以type为键与 defaultShapeUtils、defaultBindingUtils、defaultAssetUtils、defaultOverlayUtils合并——同类型传入即整体替换默认实现,这解释了“自定义一个箭头形状”为什么只需提供一个同 type 的 ShapeUtil;tools以id为键与allDefaultTools(即defaultTools+defaultShapeTools)合并;components同时覆盖编辑器组件(TLEditorComponents)与 UI 组件(TLUicomponents),二者合成为TLComponents接口(Tldraw.tsx)。文档明确提示:components、assetUrls、embeds这类对象/数组属性必须用useMemo记忆化或定义在组件外部,否则会导致不必要的重建;- 图片/视频的外部内容处理:
maxImageDimension、acceptedImageMimeTypes、acceptedVideoMimeTypes会在configureDefaultAssetUtils中透传给ImageAssetUtil/VideoAssetUtil的configure(),控制图片最大边长与可接收的 MIME 类型;未传时使用DEFAULT_SUPPORTED_IMAGE_TYPES等默认值。
组件挂载阶段(InsideOfEditorAndUiContext,Tldraw.tsx)的 useOnMount 中有一串固定动作,值得理解其顺序:
registerDefaultSideEffects(editor)—— 注册默认副作用;- 后台预载默认字体(
editor.fonts.requestFonts),并预载主题中自定义的字体; editor.once('edit', ...)记录首次编辑事件;registerDefaultExternalContentHandlers(editor, {...})—— 注册默认的文件/剪贴板内容处理器;- 依次执行 store 的
onMount与 用户onMountprop——后者最后执行,因此可以在运行时拿到Editor实例后覆盖前面的行为。这正对应 README 所说的 “Runtime API — drive the canvas at runtime with the Editor API”。
最终渲染结构是:AssetUrlsProvider → TldrawUiTranslationProvider → <TldrawEditor>(编辑器核心,初始状态为 select)→ <TldrawUi>(完整 UI:工具栏、菜单、小地图等)→ 你的 children。如果你通过 components 覆盖了 Canvas 或 ContextMenu,组件会用你的版本替换默认画布/上下文菜单(Tldraw.tsx)。
从 packages/tldraw/package.json 的依赖表还能看到 SDK 的分层:tldraw(React 封装 + 默认 UI/形状)依赖 @tldraw/editor(无 React 的编辑器核心)、@tldraw/state、@tldraw/store、@tldraw/tlschema、@tldraw/driver,富文本则基于 Tiptap 系列包实现;peerDependencies 为 react ^18.2.0 || ^19.2.1。如果你只需要无 UI 的画布逻辑,可以直接面向 @tldraw/editor 编程。
三、Starter kits:从模板到可运行项目
README 指出 Starter kits 提供“常见应用所需的自定义形状、工具与用户界面”,且每个 kit 均为 MIT 许可——可以拿去快速拼原型、在其上构建应用,或者把代码引用进更大的项目。官方推荐的入口是一条命令:
npx create-tldraw@latest
该命令由 packages/create-tldraw 提供(bin 字段指向 ./cli.cjs)。CLI 支持的模板清单在 templates.ts 中自动维护,与 README 列出的 7 个 kit 一一对应。仓库的 templates/ 目录内就包含其中几个 kit 的完整源码,可以直接查阅:
| Kit | 定位 | 仓库内可参考的源码 |
|---|---|---|
| Multiplayer | 基于 @tldraw/sync 与 Cloudflare Durable Objects 的自托管实时协作,与 tldraw.com 同款技术栈 |
templates/sync-cloudflare |
| Agent | 可以读取、理解并修改画布内容的 AI Agent | templates/agent |
| Workflow | 面向自动化流水线、可视化编程、无代码平台的拖拽式节点构建器 | templates/workflow |
| Chat | 画布驱动的 AI 聊天:用户可以在对话旁手绘、标注、在图片上做标记 | templates/chat |
| Image pipeline | 基于节点的图像生成流水线构建器 | templates/image-pipeline |
| Branching chat | 支持视觉分支的 AI 聊天,可探索与对比不同对话路径 | templates/branching-chat |
| Shader | 对画布交互做出响应的 WebGL shader | templates/shader |
除 README 列出的 7 个 kit 外,仓库 templates/ 目录还包含 vite、nextjs、vue、simple-server-example、socketio-server-example 等更基础的示例模板,templates/sync-cloudflare/arch.png 中还有一张同步架构示意图,适合想自托管协作后端时先读。
四、本地开发:在仓库里跑 examples
README.md 的 “Local development” 一节说明:开发服务器运行 examples app,地址为 localhost:5420;文档要求 Node.js ^20.0.0,并先用 corepack 启用正确的 yarn 版本。需要注意,仓库根 package.json 当前 engines 声明为 node >=22.12.0、packageManager 为 yarn@4.17.1,因此实际克隆仓库开发时建议直接使用 Node 22+,README 的 ^20.0.0 可视为下限表述:
# 1. 安装 corepack,获得仓库锁定的 yarn 版本
npm i -g corepack
# 2. 克隆仓库后,安装依赖并启动开发服务器
yarn
yarn dev
yarn dev 实际执行的是(见根 package.json):
LAZYREPO_PRETTY_OUTPUT=0 lazy run dev \
--filter='apps/examples' \
--filter='packages/tldraw' \
--filter='apps/bemo-worker' \
--filter='apps/dotcom/image-resize-worker'
即 monorepo(workspaces 覆盖 packages/*、apps/*、internal/*、templates/*)中同时启动:examples 应用(所有文档示例的运行载体,位于 apps/examples)、tldraw 包(CSS 文件监听复制,见 packages/tldraw/package.json 的 dev 脚本)、以及 bemo-worker 与 image-resize-worker 两个 worker。其余常用脚本包括:yarn dev-app(dotcom 全栈)、yarn dev-docs(文档站)、yarn build、yarn typecheck、yarn test / yarn test-ci(vitest)、yarn e2e(examples 的端到端测试)等。
五、文档体系:面向人与 Agent 的双通道
README 的 Documentation 一节给出了三层文档获取方式,这也是本仓库文档工程上比较值得借鉴的一点:
- 线上文档:最新发布版的完整文档(含
Editor的 reference 文档)在 tldraw.dev 的 docs 站;仓库内文档站源码位于 apps/docs,内容按content/docs、content/sdk-features、content/releases等目录组织,SDK 特性文档多达数十篇 mdx; - 面向 AI Agent 的 LLMs.txt:README 明确提到 “For more agent-friendly docs, see our LLMs.txt”,文档站会生成供大模型消费的 llms.txt(生成脚本见 apps/docs/scripts/create-llms-txt.ts);
- 随包发布的文档:从 5.1.x 起,每个已发布的 npm 包都附带
DOCS.md(对应文档站内容的版本快照)与生成的RELEASE_NOTES.md(该版本的发布说明)。README 建议:如果你或你的编码 Agent 需要“当前安装版本”对应的发布说明,直接在node_modules里查这些文件,而不是查最新版文档。例如 packages/sync/README.md 就写明:“ADOCS.mdfile is included alongside this README in the published package, with detailed API documentation and usage examples”。
对 Agent 驱动开发(agentic coding)来说,这意味着:安装任意 tldraw 包后,本地 node_modules 内即可获得与版本号严格匹配的 API 文档与变更日志,避免“文档是最新的、依赖是旧的”错配问题。
六、许可、贡献与社区
- 许可证:tldraw SDK 遵循 tldraw license。开发环境可自由使用;生产环境需要 license key。各 Starter kit 与模板则为 MIT 许可(README 中明确 “Each kit is MIT-licensed”)。各包的
license字段均指向SEE LICENSE IN LICENSE.md(如 packages/tldraw/package.json)。 - 贡献:README 声明 “We are not accepting contributions at this time”——目前不接受外部直接提交代码;发现 bug 或有功能需求时,通过 issue 讨论。贡献细节见 CONTRIBUTING.md。
- 社区:Discord 用于提问与讨论,Twitter/X 发布动态,issue 用于 bug 报告与功能请求。
七、小结
回到 README 的主线:tldraw SDK 的使用路径非常短——npm i tldraw,然后 <Tldraw /> 即可得到一个可交互的无限画布;npx create-tldraw@latest 则按应用场景(协作、Agent、工作流、聊天、shader 等)一步生成 MIT 许可的起步项目。而它的深度在于可扩展性:<Tldraw /> 的每个默认项(shapeUtils、bindingUtils、tools、components……)都可以通过同 type/同 id 传入整体替换,onMount 提供的 Editor 实例则构成完整的运行时 API,配合 @tldraw/sync 可以把单机画布升级为自托管的多人实时协作。建议的阅读顺序是:本文快速上手 → 仓库 templates/ 中的对应 kit 源码 → apps/examples 中对应示例 → node_modules 内与你安装版本匹配的 DOCS.md,即可在事实一致的前提下完成从集成到定制的完整闭环。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0627
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
