tldraw-mods

Publish a mod

Mods live in your own repository. The hub is a catalog: it points at your registry, validates it nightly, and lists it here.

1. Write the mod

A mod is one file, src/mods/<name>.tsx, whose default export is tldraw offline's own config-script function. Optional named exports tool and commands put it in the toolbar and context menu.

import type { ModConfig, ModTool } from '@/mod'
import { MyShapeTool, MyShapeUtil, myIcon } from './my-shape-impl'

export const tool: ModTool = { id: 'my-shape', label: 'My shape', icon: myIcon }
export default (({ config }) => {
  config.shapeUtils.push(MyShapeUtil)
  config.tools.push(MyShapeTool)
}) satisfies ModConfig

Develop it inside a workspace made by npx tldraw-mods init; npm run apply loads it into the open document.

2. Add registry.json to your repo root

{
  "$schema": "https://ui.shadcn.com/schema/registry.json",
  "name": "my-mods",
  "homepage": "https://github.com/you/my-mods",
  "items": [{
    "name": "my-shape",
    "type": "registry:component",
    "title": "My shape",
    "description": "One sentence.",
    "dependencies": ["lucide-react"],
    "registryDependencies": ["btn0s/tldraw-mods/tool-chrome"],
    "files": [{ "path": "src/mods/my-shape.tsx", "type": "registry:component", "target": "~/src/mods/my-shape.tsx" }]
  }]
}

At this point anyone can install it: npx tldraw-mods add you/my-mods/my-shape.

3. List it here

Open a pull request on btn0s/tldraw-mods adding a pointer item to registry.json:

{ "name": "my-shape", "type": "registry:component", "title": "My shape", "description": "One sentence.",
  "categories": ["shape"], "registryDependencies": ["you/my-mods/my-shape"], "files": [] }

CI validates your registry on every PR and nightly; a broken upstream is flagged, not silently dropped.