はじめに
Reactアプリにホワイトボード機能を追加したいと思ったこと、ありませんか。
自前で実装しようとすると、Canvas APIの扱い、ズーム・パン処理、図形の選択・移動・リサイズ...正直なところ、かなりの工数がかかります。
そんな時に便利なのがTldrawという無限キャンバスSDKです。
GitHubで44,000スター以上を獲得していて、Reactコンポーネントとして数行のコードでホワイトボード機能を実装できます。tldraw.comというデジタルホワイトボードサービスの基盤技術がオープンソースで公開されているので、品質も折り紙付きです。
これ、意外とSaaS開発とか社内ツール開発で重宝するんですよね。
Tldrawとは
Tldrawは、Reactで無限キャンバス体験を実現するためのSDKです。描画、図形作成、テキスト入力、画像挿入など、ホワイトボードに必要な機能が一通り揃っています。
約5年前にプロジェクトが開始され、現在は214人のコントリビューターによって活発に開発が続けられています。最新バージョンはv4.2.1(2025年12月5日リリース)です。
公式サイト: https://tldraw.dev デモサイト: https://tldraw.com GitHub: https://github.com/tldraw/tldraw
特徴・メリット
1. 導入が圧倒的に簡単
これがTldrawの最大の魅力です。
npmパッケージをインストールして、コンポーネントを配置するだけ。文字通り数行のコードでホワイトボード機能が完成します。
Canvas APIを直接扱う必要がないので、開発工数を大幅に削減できます。個人的にはこの「すぐ動く」感じがめちゃくちゃ気に入ってます。
2. 無限キャンバス
キャンバスに制限がありません。
どこまでもズームアウトできて、どこまでもパンできる。複数のダイアグラムを同じキャンバスに配置したり、巨大なマインドマップを作ったり。自由度が高いです。
3. 豊富な描画ツール
標準で以下のツールが使えます。
- ペン(フリーハンド描画)
- 図形(矩形、楕円、三角形など)
- 矢印・線
- テキスト
- 付箋
- 画像埋め込み
- フレーム
ホワイトボードに必要な機能は一通り揃ってますね。
4. リアルタイムコラボレーション対応
複数人での同時編集にも対応しています。
Yjs等のCRDTライブラリと組み合わせることで、リアルタイムコラボレーション機能を実装できます。リモートワークでのチーム作業に便利。
5. 高いカスタマイズ性
UIのカスタマイズ、独自ツールの追加、カスタムシェイプの作成など、細かいところまで手が届きます。
SDKとして提供されているので、自分のアプリの要件に合わせて自由に拡張できるのが強みです。
6. TypeScript完全対応
型定義が完備されているので、TypeScriptプロジェクトでも安心して使えます。
エディタの補完が効くので、開発効率が上がりますね。
インストール方法
npm install tldraw
# または
yarn add tldraw
# または
pnpm add 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のインポートを忘れないこと。これがないとスタイルが崩れます。
コンテナサイズの指定
Tldrawコンポーネントは親要素のサイズに合わせて表示されます。親要素のサイズが0だと何も表示されないので、必ずサイズを指定してください。
// 全画面表示
<div style={{ position: 'fixed', inset: 0 }}>
<Tldraw />
</div>
// 固定サイズ
<div style={{ width: '800px', height: '600px' }}>
<Tldraw />
</div>
// 親要素に合わせる
<div style={{ width: '100%', height: '500px' }}>
<Tldraw />
</div>
状態の永続化
import { Tldraw } from 'tldraw'
import 'tldraw/tldraw.css'
export default function App() {
return (
<div style={{ position: 'fixed', inset: 0 }}>
<Tldraw
persistenceKey="my-whiteboard"
/>
</div>
)
}
persistenceKeyを指定すると、ブラウザのローカルストレージに自動保存されます。ページをリロードしても内容が保持されるので、ちょっとしたメモ用途なら十分ですね。
エディターの操作
import { Tldraw, Editor } from 'tldraw'
import 'tldraw/tldraw.css'
export default function App() {
const handleMount = (editor: Editor) => {
// エディターのインスタンスを取得
console.log('Editor mounted:', editor)
// 現在のシェイプを取得
const shapes = editor.getCurrentPageShapes()
console.log('Shapes:', shapes)
// ズームレベルを変更
editor.setCamera({ x: 0, y: 0, z: 1 })
}
return (
<div style={{ position: 'fixed', inset: 0 }}>
<Tldraw onMount={handleMount} />
</div>
)
}
onMountコールバックでEditorインスタンスを取得できます。これを使えば、プログラムから図形を追加したり、キャンバスを操作したりできます。
ダークモード対応
import { Tldraw } from 'tldraw'
import 'tldraw/tldraw.css'
export default function App() {
return (
<div style={{ position: 'fixed', inset: 0 }}>
<Tldraw
inferDarkMode
/>
</div>
)
}
inferDarkModeを指定すると、システムの設定に合わせて自動的にダークモードが切り替わります。
読み取り専用モード
import { Tldraw, Editor } from 'tldraw'
import 'tldraw/tldraw.css'
export default function App() {
const handleMount = (editor: Editor) => {
editor.updateInstanceState({ isReadonly: true })
}
return (
<div style={{ position: 'fixed', inset: 0 }}>
<Tldraw onMount={handleMount} />
</div>
)
}
閲覧専用で表示したい場合は、isReadonlyを設定します。
実践的なユースケース
1. ドキュメントツールへの組み込み
NotionやConfluenceのような社内Wikiに、図解機能を追加するケース。
テキストだけでは伝わりにくい内容を、その場で図解できると便利ですよね。Tldrawなら数行で実装できます。
2. オンラインミーティングツール
Zoomのホワイトボード機能みたいなものを自前で作りたい時に使えます。
リアルタイムコラボ機能と組み合わせれば、チームでのブレインストーミングツールが作れます。
3. 教育・研修システム
オンライン授業で先生が板書できる機能とか、受講者が解答を書き込める機能とか。
教育系のサービスではよくあるユースケースですね。
4. デザインフィードバックツール
デザインカンプに対して、直接注釈を書き込めるレビューツール。
Figmaのコメント機能みたいなものを自前で作りたい時に便利です。
5. マインドマップ・フローチャート作成
import { Tldraw, Editor, createShapeId } from 'tldraw'
import 'tldraw/tldraw.css'
export default function App() {
const handleMount = (editor: Editor) => {
// プログラムから図形を追加
const shapeId = createShapeId()
editor.createShape({
id: shapeId,
type: 'geo',
x: 100,
y: 100,
props: {
geo: 'rectangle',
w: 200,
h: 100,
text: 'メインアイデア',
},
})
}
return (
<div style={{ position: 'fixed', inset: 0 }}>
<Tldraw onMount={handleMount} />
</div>
)
}
APIを使えば、データから自動的にマインドマップやフローチャートを生成することも可能です。
注意点
いくつか気をつけるポイントがあります。
1. ライセンスについて
Tldrawはカスタムライセンスで提供されています。
無料で使えますが、キャンバスに「Made with tldraw」のウォーターマークが表示されます。商用プロダクトでウォーターマークを削除したい場合は、ビジネスライセンスの購入が必要です。
個人プロジェクトや社内ツールなら問題ないですが、顧客向けサービスに組み込む場合はライセンスを確認しておきましょう。
2. バンドルサイズ
高機能なライブラリなので、それなりにサイズがあります。
パフォーマンスが気になる場合は、動的インポートで遅延読み込みすることをおすすめします。
import dynamic from 'next/dynamic'
const Tldraw = dynamic(() => import('tldraw').then(mod => mod.Tldraw), {
ssr: false,
loading: () => <p>Loading...</p>,
})
3. SSR非対応
ブラウザAPIに依存しているため、サーバーサイドレンダリングには対応していません。
Next.jsで使う場合は、上記のようにssr: falseを指定するか、'use client'ディレクティブを使ってクライアントコンポーネントにする必要があります。
Excalidrawとの比較
同じ無限キャンバス系のツールとして、Excalidrawと比較されることが多いです。
| 項目 | Tldraw | Excalidraw |
|---|---|---|
| スタイル | きれいめ | 手書き風 |
| ライセンス | カスタム(ウォーターマーク付き) | MIT |
| SDK設計 | 本格的 | シンプル |
| カスタマイズ性 | 高い | 中程度 |
Tldrawは「SDKとして自分のアプリに組み込む」用途に強く、Excalidrawは「手軽に手書き風の図を描く」用途に強い印象です。
用途に応じて使い分けるのがいいですね。
まとめ
Tldrawは「Reactアプリにホワイトボード機能を追加したい」というニーズにぴったりのSDKです。
- 数行のコードで導入できる
- 無限キャンバスで自由にレイアウト
- リアルタイムコラボレーション対応
- 高いカスタマイズ性
- TypeScript完全対応
個人的には、自前でCanvas APIを触る苦行から解放されるだけでも価値があると思います。SDKとしての設計がしっかりしているので、本格的なプロダクト開発にも耐えられます。
30代になって思うのは、「車輪の再発明はしない」ということ。こういう高品質なOSSを活用して、本当に作りたい機能の開発に集中するのが効率的ですね。
興味がある人は、まずtldraw.comでデモを触ってみてください。実際に使ってみると、その完成度の高さがわかると思います。
公式サイト: https://tldraw.dev デモサイト: https://tldraw.com GitHub: https://github.com/tldraw/tldraw npm: tldraw