# plait-board/drawnix architecture

> Architecture diagram of the GitHub repository plait-board/drawnix, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-30). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/plait-board/drawnix
- Repository: https://github.com/plait-board/drawnix

## Overview

1. **Repository shape: a monorepo with layered packages**
   - This is an Nx-managed TypeScript monorepo.
   - The architecture is split into a small deployable web app and several reusable packages:
     - `apps/web` = the shipped browser application shell
     - `packages/drawnix` = the main whiteboard product logic and UI
     - `packages/react-board` = React adapter/view layer for the board
     - `packages/react-text` = text rendering/editing module
   - Per-package Vite configs and TS configs indicate each package can be built and tested independently.

2. **Product core: `packages/drawnix` is the main editor subsystem**
   - This package contains the bulk of the whiteboard experience: canvas tools, toolbars, dialogs, menus, toasts, i18n, styles, and editor hooks.
   - It is the domain layer that users actually interact with: drawing, mind maps, flowcharts, freehand, images, links, zoom, theme switching, and export/import features.
   - The README’s “all-in-one whiteboard” description matches this package being the heart of the product.

3. **Rendering and board integration: `packages/react-board`**
   - `react-board` is the React-facing wrapper around the underlying board engine.
   - It provides hooks and plugins for React integration, including event handling and pinch-zoom behavior.
   - This is the boundary where React UI code talks to the board/canvas runtime.

4. **Text subsystem: `packages/react-text`**
   - Text editing and rendering are isolated into a separate package.
   - It includes text plugins and link handling, showing that text is treated as a distinct editor capability rather than a simple label field.
   - This separation matters because text is a cross-cutting concern across shapes, links, and rich content.

5. **Plugin architecture is the main extension boundary**
   - The repo is explicitly plugin-driven.
   - Core plugin families include:
     - general behavior plugins (`with-common`, `with-hotkey`, `with-tool-state-sync`)
     - drawing/input plugins (`with-pencil`, freehand plugins, image plugin)
     - content plugins (`with-text-link`, mind extension)
   - In architecture terms, user actions are mediated by plugins rather than hard-coded into one monolith.

6. **Tooling and UX are organized as independent UI modules**
   - The `components` tree under `packages/drawnix` is heavily modularized: toolbars, popovers, dialogs, menus, pickers, sliders, and toasts.
   - These are not just visual widgets; they are the control surface for editor state and tool selection.
   - The toolbar/popup/dialog split suggests a clear separation between persistent editor controls and transient editing overlays.

7. **Content types and serialization form the data boundary**
   - The `data` modules cover blob, filesystem, image, and JSON handling.
   - This strongly suggests the application can import/export board state and external assets through dedicated serialization paths.
   - The README confirms key outputs: PNG, JSON (`.drawnix`), and browser-cache autosave.
   - In diagrams, this is the persistence/export boundary: board state inside, serialized artifacts outside.

8. **Text-to-diagram conversion is a distinct ingestion pipeline**
   - The `ttd-dialog` module handles “text to drawnix” flows.
   - It includes converters for Mermaid and Markdown into board content.
   - This is an important architectural path because it turns external textual specifications into native board objects, rather than requiring manual drawing.

9. **App shell and deployment are intentionally minimal**
   - `apps/web` is a minimal web app with static assets, redirects, headers, and a single React entry point.
   - That suggests the product is delivered as a static frontend rather than a server-rendered app.
   - The presence of Cloudflare deployment docs and `_headers`/`_redirects` files indicates static hosting/CDN-oriented delivery, likely on Cloudflare Pages.
   - `Dockerfile` and publish scripts support packaging/release, but the runtime is still browser-based.

10. **Cross-cutting concerns: localization, themes, and shared styling**
   - `i18n` and translation files indicate runtime language switching is a first-class feature.
   - Shared SCSS variables and theme files show theme consistency across the UI and board components.
   - These cross-cutting layers sit below the UI components but above the board core, so they affect nearly every visible subsystem.

11. **Quality gates and validation are split by scope**
   - Unit/component tests exist in the packages, and `apps/web-e2e` uses Playwright for end-to-end coverage.
   - This mirrors the architecture: package-level behavior is tested close to the code, while the browser app is validated through full UI flows.
   - CI workflows and release scripts indicate automated build/test/publish boundaries around the monorepo.

12. **Mental model for an architecture diagram**
   - A good diagram would show: browser app shell → React board adapter → Drawnix core/plugins → board state/data/serialization → export/import and browser persistence.
   - Side paths should include: toolbar/dialog UI, text subsystem, freehand/image/diagram converters, localization/theme layers, and external static hosting/release tooling.
   - The most important conceptual boundary is between the reusable editor engine (`packages/*`) and the minimal deployable app (`apps/web`).

Main entry points: [`packages/drawnix/src/drawnix.tsx`](https://github.com/plait-board/drawnix/blob/develop/packages/drawnix/src/drawnix.tsx) (Editor shell), [`packages/drawnix/src/plugins`](https://github.com/plait-board/drawnix/tree/develop/packages/drawnix/src/plugins) (Plugins), [`packages/react-board`](https://github.com/plait-board/drawnix/tree/develop/packages/react-board) (Board adapter), [`apps/web`](https://github.com/plait-board/drawnix/tree/develop/apps/web) (Web app)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_apps["App shell"]
  node_web_app["Web app<br/>static SPA"]
  node_web_e2e["Web e2e<br/>browser tests"]
end

subgraph group_drawnix["Drawnix core"]
  node_editor_shell["Editor shell<br/>whiteboard UI<br/>[drawnix.tsx]"]
  node_toolbar_ui["Toolbars<br/>control surface"]
  node_dialog_ui["Dialogs<br/>overlay UI"]
  node_ttd_dialog["Text to diagram<br/>ingestion flow"]
  node_plugin_core["Plugins<br/>extension layer"]
  node_freehand["Freehand<br/>drawing plugin"]
  node_content_data[("Data model<br/>serialization")]
  node_i18n_theme["Locale & theme<br/>cross-cutting"]
  node_utils_core["Utilities<br/>shared helpers"]
end

subgraph group_adapters["Adapters"]
  node_board_adapter["Board adapter<br/>React bridge"]
  node_text_adapter["Text module<br/>React text"]
  node_board_runtime["Board runtime<br/>canvas engine<br/>[board.tsx]"]
  node_react_plugins["React plugins<br/>integration plugins"]
  node_text_plugins["Text plugins<br/>text extensions"]
end

subgraph group_tooling["Tooling"]
  node_build_release["Build & release<br/>monorepo tooling"]
end

node_web_app -->|"mounts"| node_board_adapter
node_web_app -->|"hosts"| node_editor_shell
node_web_e2e -->|"validates"| node_web_app
node_board_adapter -->|"wraps"| node_board_runtime
node_board_adapter -->|"applies"| node_react_plugins
node_board_adapter -->|"feeds"| node_editor_shell
node_text_adapter -->|"extends"| node_text_plugins
node_text_adapter -->|"supplies"| node_editor_shell
node_editor_shell -->|"orchestrates"| node_plugin_core
node_editor_shell -->|"presents"| node_toolbar_ui
node_editor_shell -->|"opens"| node_dialog_ui
node_editor_shell -->|"imports"| node_ttd_dialog
node_plugin_core -->|"includes"| node_freehand
node_plugin_core -->|"serializes"| node_content_data
node_plugin_core -->|"uses"| node_i18n_theme
node_toolbar_ui -->|"shares"| node_i18n_theme
node_dialog_ui -->|"imports/exports"| node_content_data
node_ttd_dialog -->|"produces"| node_content_data
node_ttd_dialog -->|"converts"| node_text_adapter
node_content_data -.->|"packages"| node_build_release
node_web_app -->|"deployed by"| node_build_release

click node_web_app "https://github.com/plait-board/drawnix/tree/develop/apps/web"
click node_web_e2e "https://github.com/plait-board/drawnix/tree/develop/apps/web-e2e"
click node_board_adapter "https://github.com/plait-board/drawnix/tree/develop/packages/react-board"
click node_text_adapter "https://github.com/plait-board/drawnix/tree/develop/packages/react-text"
click node_editor_shell "https://github.com/plait-board/drawnix/blob/develop/packages/drawnix/src/drawnix.tsx"
click node_toolbar_ui "https://github.com/plait-board/drawnix/tree/develop/packages/drawnix/src/components/toolbar"
click node_dialog_ui "https://github.com/plait-board/drawnix/tree/develop/packages/drawnix/src/components"
click node_ttd_dialog "https://github.com/plait-board/drawnix/tree/develop/packages/drawnix/src/components/ttd-dialog"
click node_plugin_core "https://github.com/plait-board/drawnix/tree/develop/packages/drawnix/src/plugins"
click node_freehand "https://github.com/plait-board/drawnix/tree/develop/packages/drawnix/src/plugins/freehand"
click node_content_data "https://github.com/plait-board/drawnix/tree/develop/packages/drawnix/src/data"
click node_i18n_theme "https://github.com/plait-board/drawnix/tree/develop/packages/drawnix/src/i18n"
click node_utils_core "https://github.com/plait-board/drawnix/tree/develop/packages/drawnix/src/utils"
click node_board_runtime "https://github.com/plait-board/drawnix/blob/develop/packages/react-board/src/board.tsx"
click node_react_plugins "https://github.com/plait-board/drawnix/tree/develop/packages/react-board/src/plugins"
click node_text_plugins "https://github.com/plait-board/drawnix/tree/develop/packages/react-text/src/plugins"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_web_app,node_web_e2e toneBlue
class node_editor_shell,node_toolbar_ui,node_dialog_ui,node_ttd_dialog,node_plugin_core,node_freehand,node_content_data,node_i18n_theme,node_utils_core toneAmber
class node_board_adapter,node_text_adapter,node_board_runtime,node_react_plugins,node_text_plugins toneMint
class node_build_release toneRose
```

## Components

### App shell

Deployable browser app and end-to-end coverage.

- [Web app](https://github.com/plait-board/drawnix/tree/develop/apps/web): static SPA · Minimal shipped browser shell and entry point. · `apps/web`
- [Web e2e](https://github.com/plait-board/drawnix/tree/develop/apps/web-e2e): browser tests · Playwright coverage for full app flows. · `apps/web-e2e`

### Drawnix core

Main whiteboard editor package with UI, plugins, data, and cross-cutting concerns.

- [Editor shell](https://github.com/plait-board/drawnix/blob/develop/packages/drawnix/src/drawnix.tsx): whiteboard UI · Top-level Drawnix entry, hooks, and app composition. · `packages/drawnix/src/drawnix.tsx`
- [Toolbars](https://github.com/plait-board/drawnix/tree/develop/packages/drawnix/src/components/toolbar): control surface · Persistent editor controls for tools, zoom, theme, and creation actions. · `packages/drawnix/src/components/toolbar`
- [Dialogs](https://github.com/plait-board/drawnix/tree/develop/packages/drawnix/src/components): overlay UI · Transient dialogs, popovers, menus, toasts, and pickers. · `packages/drawnix/src/components`
- [Text to diagram](https://github.com/plait-board/drawnix/tree/develop/packages/drawnix/src/components/ttd-dialog): ingestion flow · Converts Mermaid or Markdown into native board content. · `packages/drawnix/src/components/ttd-dialog`
- [Plugins](https://github.com/plait-board/drawnix/tree/develop/packages/drawnix/src/plugins): extension layer · Common, hotkey, tool sync, pencil, image, text-link, and mind plugins. · `packages/drawnix/src/plugins`
- [Freehand](https://github.com/plait-board/drawnix/tree/develop/packages/drawnix/src/plugins/freehand): drawing plugin · Stroke generation, smoothing, erasing, and fragment handling. · `packages/drawnix/src/plugins/freehand`
- [Data model](https://github.com/plait-board/drawnix/tree/develop/packages/drawnix/src/data): serialization · Blob, filesystem, image, and JSON boundaries for import/export. · `packages/drawnix/src/data`
- [Locale & theme](https://github.com/plait-board/drawnix/tree/develop/packages/drawnix/src/i18n): cross-cutting · Translations, theme tokens, and shared styling. · `packages/drawnix/src/i18n`
- [Utilities](https://github.com/plait-board/drawnix/tree/develop/packages/drawnix/src/utils): shared helpers · Common helpers, color, image, property, and pointer utilities. · `packages/drawnix/src/utils`

### Adapters

React-facing integration layers around the board and text subsystems.

- [Board adapter](https://github.com/plait-board/drawnix/tree/develop/packages/react-board): React bridge · React wrapper and hooks for the board runtime. · `packages/react-board`
- [Text module](https://github.com/plait-board/drawnix/tree/develop/packages/react-text): React text · Isolated text rendering and editing package. · `packages/react-text`
- [Board runtime](https://github.com/plait-board/drawnix/blob/develop/packages/react-board/src/board.tsx): canvas engine · Underlying board state and event layer exposed through React. · `packages/react-board/src/board.tsx`
- [React plugins](https://github.com/plait-board/drawnix/tree/develop/packages/react-board/src/plugins): integration plugins · React-specific board plugins including pinch zoom and event wiring. · `packages/react-board/src/plugins`
- [Text plugins](https://github.com/plait-board/drawnix/tree/develop/packages/react-text/src/plugins): text extensions · Text and link plugin layer for rich labels and inline linking. · `packages/react-text/src/plugins`

### Tooling

Monorepo build, test, release, and deployment support.

- **Build & release**: monorepo tooling · Nx, Vite, CI, publish scripts, and deployment packaging.

## Connections

- Web app → Board adapter: mounts · The browser shell renders the reusable board adapter.
- Web app → Editor shell: hosts · The app shell hosts the main editor experience.
- Web e2e → Web app: validates · End-to-end tests exercise the shipped browser app.
- Board adapter → Board runtime: wraps · React hooks and wrappers sit on top of the board runtime.
- Board adapter → React plugins: applies · React integration is extended through board plugins.
- Board adapter → Editor shell: feeds · The adapter provides the runtime boundary used by Drawnix UI.
- Text module → Text plugins: extends · Text rendering and editing are composed via text plugins.
- Text module → Editor shell: supplies · Text editing is consumed by the main editor subsystem.
- Editor shell → Plugins: orchestrates · The editor shell coordinates behavior through plugins.
- Editor shell → Toolbars: presents · The shell exposes the persistent tool and mode controls.
- Editor shell → Dialogs: opens · The shell uses dialogs and popovers for transient editor actions.
- Editor shell → Text to diagram: imports · Text-to-diagram conversion is part of the editor surface.
- Plugins → Freehand: includes · Freehand editing is implemented as a dedicated plugin family.
- Plugins → Data model: serializes · Plugins hand off board content through the data boundary.
- Plugins → Locale & theme: uses · Plugin-driven UI is styled and localized through shared concerns.
- Toolbars → Locale & theme: shares · Toolbars depend on locale and theme assets.
- Dialogs → Data model: imports/exports · Dialogs and menus feed serialization, asset, and file flows.
- Text to diagram → Data model: produces · Converted content becomes native board data.
- Text to diagram → Text module: converts · Markdown and Mermaid are translated into text/board structures.
- Data model → Build & release: packages · Serialized artifacts support publish, export, and deployment flows.
- Web app → Build & release: deployed by · Static hosting and CI/release scripts ship the browser app.
