--- title: Getting started with jeeboard description: Shows how to install the jeeboard packages and wire a minimal editor with a canvas renderer. --- # Getting started This guide builds a minimal editor. The editor shows one rectangle on an infinite canvas. It has no tools and no persistence. Later sections link to the packages that add these features. ## Install Install the packages for the minimal editor: ```sh pnpm add @jeeboard/core @jeeboard/dom @jeeboard/renderer-canvas2d ``` - `@jeeboard/core` holds the elements and the change history. - `@jeeboard/dom` marks the host element for the editor. - `@jeeboard/renderer-canvas2d` draws the elements. ## Prepare the page Add a host element and a canvas to your HTML: ```html
``` Give the canvas a size with CSS. The renderer reads the CSS size when you call `resize`. ## Create the editor core The editor core holds all elements. Create it and add one element in a transaction: ```ts import { createEditorCore, elementId } from "@jeeboard/core"; const core = createEditorCore(); core.transact("create rectangle", (tx) => tx.create({ id: elementId("rectangle-1"), type: "shape", bounds: { x: 0, y: 0, width: 160, height: 100 }, properties: { shape: "rectangle" }, }) ); ``` Each transaction that mutates elements becomes one undo step. See [@jeeboard/core](core/index.md) for the full data model. ## Create the renderer Create the renderer on the canvas element: ```ts import { createCanvas2DRenderer, type Camera, } from "@jeeboard/renderer-canvas2d"; const canvas = document.querySelector("#board")!; const renderer = createCanvas2DRenderer(canvas, { background: "#ffffff" }); const camera: Camera = { center: { x: 80, y: 50 }, zoom: 1 }; renderer.resize(canvas.clientWidth, canvas.clientHeight, window.devicePixelRatio); ``` The camera has a center point in world coordinates and a zoom factor. The zoom must be finite and positive. ## Mark the host element Attach the editor core to the host element: ```ts import { createEditorHost } from "@jeeboard/dom"; const editorHost = createEditorHost(document.getElementById("editor")!); editorHost.attach(core); ``` The `attach` method sets the `data-jeeboard-editor` attribute and an aria label. See [@jeeboard/dom](dom/index.md) for text portals and the accessibility mirror. ## Render frames Render one frame now. Render a new frame each time the core changes: ```ts function renderFrame(): void { renderer.present({ camera, visibleElements: core.list(), }); } renderFrame(); core.subscribe(() => renderFrame()); ``` NOTE: `core.list()` returns all elements. For large boards, query only the visible elements with the spatial index from [@jeeboard/scene](scene/index.md). Check `renderer.diagnostics().pendingTileCount` after `present`. Request another animation frame when the count is greater than zero. The renderer then rasterizes the remaining tiles. ## Next steps Add the features that your editor needs: 1. Add [@jeeboard/scene](scene/index.md) for fast viewport queries and hit tests. 2. Add [@jeeboard/ink](ink/index.md) for freehand strokes. 3. Add [@jeeboard/text-prosemirror](text-prosemirror/index.md) for rich-text editing. 4. Add [@jeeboard/storage](storage/index.md) for local persistence. 5. Add [@jeeboard/automerge](automerge/index.md) for CRDT sync and collaboration. The [playground](playground/index.md) is a complete application that composes all packages. Use it as the reference for a full integration.