# katsu996/miro architecture

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

- Interactive diagram: https://gitdiagram.com/katsu996/miro
- Repository: https://github.com/katsu996/miro

## Overview

1. **Overall shape**
   - This is a **browser-only whiteboard app** built with **Next.js App Router + React + TypeScript**.
   - There is **no backend API, auth service, or database**. All application data lives in the user’s browser via **LocalStorage**.

2. **Runtime boundary**
   - The app is designed to be **stateless on the server** and **persistent only on the client**.
   - Deployment targets **static hosting** (GitHub Pages), so the architecture is essentially: **static app bundle → browser → local persistence**.

3. **Application entry**
   - `app/layout.tsx` provides the root document structure and global styling.
   - `app/page.tsx` is the main page entry and mounts the top-level React app from `components/App.tsx`.

4. **Top-level UI composition**
   - `components/App.tsx` is the main orchestrator.
   - It likely switches between the **board dashboard** and the **active whiteboard editor**, coordinating board selection and editor state.

5. **Board management subsystem**
   - `components/Dashboard.tsx` represents the **multi-board overview**: create, rename, delete, and preview boards.
   - The README indicates thumbnail previews, so the dashboard is the navigation/control layer for switching between boards.

6. **Whiteboard editor subsystem**
   - `components/Whiteboard.tsx` is the core editing surface.
   - It handles the **infinite canvas**, pan/zoom, selection, drawing, object manipulation, and the main interaction model.
   - `components/ItemView.tsx` is the per-item rendering layer, separating generic board logic from rendering of individual items.

7. **Content model**
   - `lib/types.ts` defines the board/item domain model: sticky notes, shapes, text boxes, pen strokes, connectors, selection state, and probably board metadata.
   - `lib/constants.ts` centralizes shared defaults such as colors, sizes, tool modes, and editor constants.
   - `lib/utils.ts` contains shared geometry and editor helpers, likely including hit testing, snapping, bounding-box math, and transformation logic.

8. **Persistence and state flow**
   - `lib/storage.ts` is the persistence boundary and wraps **LocalStorage** access.
   - Data flow is: **user action → React state update → serialize to LocalStorage → reload/restore on next visit**.
   - Because storage is browser-local, boards are isolated per browser profile/device.

9. **Rendering approach**
   - The README states the editor uses **SVG-based drawing** and does not rely on an external canvas library.
   - That means shapes, connectors, text, and strokes are rendered as structured SVG elements rather than a third-party scene graph.

10. **Interaction model**
   - The editor supports multiple tools: select, hand/pan, sticky note, shape, text, pen, and connector.
   - Common operations include **multi-select, move, resize, duplicate, delete, z-order changes, undo/redo, and clipboard actions**.
   - The architecture therefore centers on a single editor state machine that interprets mouse/touch/keyboard input into board mutations.

11. **Connector and object coupling**
   - Connectors snap to shapes/stickies and follow them when endpoints move.
   - This implies a dependency graph between connectors and attached items, handled inside the editor/utility layer rather than as a separate service.

12. **Mobile and gesture support**
   - The same editor supports **touch input**, including one-finger interaction and two-finger pan/pinch zoom.
   - This is important architecturally because input handling is unified across mouse, keyboard, and touch rather than split into separate apps.

13. **Tooling and deployment**
   - `next.config.ts` plus the README’s “static export” setup indicate a build that outputs to `out/` for static hosting.
   - `.github/workflows/deploy.yml` automates build and deployment to **GitHub Pages**.
   - `scripts/smoke-test.mjs` is a post-build validation step, likely checking that the exported site is usable before deployment.

14. **Public hosting details**
   - `public/.nojekyll` is a GitHub Pages compatibility file, preventing Jekyll processing of the static export.
   - The app is therefore intended to be served as a pure static artifact with no server-side rendering dependency at runtime.

Main entry points: [`components/Whiteboard.tsx`](https://github.com/katsu996/miro/blob/main/components/Whiteboard.tsx) (Whiteboard), [`components/App.tsx`](https://github.com/katsu996/miro/blob/main/components/App.tsx) (App shell), [`components/ItemView.tsx`](https://github.com/katsu996/miro/blob/main/components/ItemView.tsx) (Item view), [`.github/workflows/deploy.yml`](https://github.com/katsu996/miro/blob/main/.github/workflows/deploy.yml) (Deploy workflow)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_runtime["Runtime boundary"]
end

subgraph group_ui["UI shell"]
  node_app_layout["Root layout<br/>Next.js layout<br/>[layout.tsx]"]
  node_app_page["Main page<br/>Next.js page<br/>[page.tsx]"]
  node_app_shell["App shell<br/>React orchestrator<br/>[App.tsx]"]
  node_globals_css["Global styles<br/>App CSS<br/>[globals.css]"]
end

subgraph group_editor["Whiteboard system"]
  node_dashboard["Dashboard<br/>Board overview<br/>[Dashboard.tsx]"]
  node_whiteboard["Whiteboard<br/>Editor surface<br/>[Whiteboard.tsx]"]
  node_item_view["Item view<br/>Item renderer<br/>[ItemView.tsx]"]
  node_icons["Icons<br/>[Icons.tsx]"]
end

subgraph group_core["Shared logic"]
  node_types["Domain types<br/>Board model<br/>[types.ts]"]
  node_constants["Constants<br/>Editor defaults<br/>[constants.ts]"]
  node_utils["Utils<br/>Geometry helpers<br/>[utils.ts]"]
  node_storage[("Storage<br/>[storage.ts]")]
end

subgraph group_ops["Build and deploy"]
  node_next_config["Next config<br/>Build config<br/>[next.config.ts]"]
  node_deploy_workflow["Deploy workflow<br/>GitHub Actions<br/>[deploy.yml]"]
  node_smoke_test["Smoke test<br/>Post-build check<br/>[smoke-test.mjs]"]
  node_nojekyll[".nojekyll<br/>Pages marker<br/>[.nojekyll]"]
end

node_app_page -->|"mounts"| node_app_shell
node_app_layout -->|"loads"| node_globals_css
node_app_shell -->|"shows"| node_dashboard
node_app_shell -->|"shows"| node_whiteboard
node_app_shell -->|"persists"| node_storage
node_dashboard -->|"reads/writes"| node_storage
node_whiteboard -->|"uses"| node_types
node_whiteboard -->|"uses"| node_constants
node_whiteboard -->|"uses"| node_utils
node_whiteboard -->|"saves"| node_storage
node_whiteboard -->|"renders"| node_item_view
node_item_view -->|"uses"| node_types
node_item_view -->|"uses"| node_constants
node_item_view -->|"uses"| node_icons
node_utils -->|"uses"| node_types
node_deploy_workflow -->|"builds with"| node_next_config
node_deploy_workflow -->|"verifies"| node_smoke_test
node_deploy_workflow -->|"publishes"| node_nojekyll
node_next_config -->|"exports"| node_app_page

click node_app_layout "https://github.com/katsu996/miro/blob/main/app/layout.tsx"
click node_app_page "https://github.com/katsu996/miro/blob/main/app/page.tsx"
click node_app_shell "https://github.com/katsu996/miro/blob/main/components/App.tsx"
click node_dashboard "https://github.com/katsu996/miro/blob/main/components/Dashboard.tsx"
click node_whiteboard "https://github.com/katsu996/miro/blob/main/components/Whiteboard.tsx"
click node_item_view "https://github.com/katsu996/miro/blob/main/components/ItemView.tsx"
click node_icons "https://github.com/katsu996/miro/blob/main/components/Icons.tsx"
click node_types "https://github.com/katsu996/miro/blob/main/lib/types.ts"
click node_constants "https://github.com/katsu996/miro/blob/main/lib/constants.ts"
click node_utils "https://github.com/katsu996/miro/blob/main/lib/utils.ts"
click node_storage "https://github.com/katsu996/miro/blob/main/lib/storage.ts"
click node_globals_css "https://github.com/katsu996/miro/blob/main/app/globals.css"
click node_next_config "https://github.com/katsu996/miro/blob/main/next.config.ts"
click node_deploy_workflow "https://github.com/katsu996/miro/blob/main/.github/workflows/deploy.yml"
click node_smoke_test "https://github.com/katsu996/miro/blob/main/scripts/smoke-test.mjs"
click node_nojekyll "https://github.com/katsu996/miro/blob/main/public/.nojekyll"

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_app_layout,node_app_page,node_app_shell,node_globals_css toneAmber
class node_dashboard,node_whiteboard,node_item_view,node_icons toneMint
class node_types,node_constants,node_utils,node_storage toneRose
class node_next_config,node_deploy_workflow,node_smoke_test,node_nojekyll toneIndigo
```

## Components

### UI shell

Root app structure and top-level screen composition.

- [Root layout](https://github.com/katsu996/miro/blob/main/app/layout.tsx): Next.js layout · Defines the root document shell and global app structure. · `app/layout.tsx`
- [Main page](https://github.com/katsu996/miro/blob/main/app/page.tsx): Next.js page · Top-level entry that mounts the application. · `app/page.tsx`
- [App shell](https://github.com/katsu996/miro/blob/main/components/App.tsx): React orchestrator · Coordinates dashboard vs active board and overall app state. · `components/App.tsx`
- [Global styles](https://github.com/katsu996/miro/blob/main/app/globals.css): App CSS · Global styling for the application shell and editor. · `app/globals.css`

### Whiteboard system

Dashboard and whiteboard editing surface.

- [Dashboard](https://github.com/katsu996/miro/blob/main/components/Dashboard.tsx): Board overview · Board listing and management surface for create, rename, delete, and switching boards. · `components/Dashboard.tsx`
- [Whiteboard](https://github.com/katsu996/miro/blob/main/components/Whiteboard.tsx): Editor surface · Main infinite-canvas editor handling selection, pan/zoom, drawing, and object manipulation. · `components/Whiteboard.tsx`
- [Item view](https://github.com/katsu996/miro/blob/main/components/ItemView.tsx): Item renderer · Renders individual board items inside the editor. · `components/ItemView.tsx`
- [Icons](https://github.com/katsu996/miro/blob/main/components/Icons.tsx): UI icons · Shared icon set used across the interface. · `components/Icons.tsx`

### Shared logic

Domain model, constants, utilities, and storage.

- [Domain types](https://github.com/katsu996/miro/blob/main/lib/types.ts): Board model · Shared board, item, tool, and selection data model definitions. · `lib/types.ts`
- [Constants](https://github.com/katsu996/miro/blob/main/lib/constants.ts): Editor defaults · Shared defaults for tools, colors, sizes, and editor behavior. · `lib/constants.ts`
- [Utils](https://github.com/katsu996/miro/blob/main/lib/utils.ts): Geometry helpers · Shared math and editor helpers for hit testing, bounds, snapping, and transforms. · `lib/utils.ts`
- [Storage](https://github.com/katsu996/miro/blob/main/lib/storage.ts): LocalStorage · Browser persistence boundary for saving and restoring boards. · `lib/storage.ts`

### Build and deploy

Static export and GitHub Pages deployment.

- [Next config](https://github.com/katsu996/miro/blob/main/next.config.ts): Build config · Configures Next.js for static export and hosting. · `next.config.ts`
- [Deploy workflow](https://github.com/katsu996/miro/blob/main/.github/workflows/deploy.yml): GitHub Actions · Builds and deploys the exported site to GitHub Pages. · `.github/workflows/deploy.yml`
- [Smoke test](https://github.com/katsu996/miro/blob/main/scripts/smoke-test.mjs): Post-build check · Validates the exported site after build. · `scripts/smoke-test.mjs`
- [.nojekyll](https://github.com/katsu996/miro/blob/main/public/.nojekyll): Pages marker · Prevents Jekyll processing on GitHub Pages. · `public/.nojekyll`

## Connections

- Main page → App shell: mounts · Main page renders the application shell.
- Root layout → Global styles: loads · Root layout applies global styling.
- App shell → Dashboard: shows · Shell can present the board dashboard.
- App shell → Whiteboard: shows · Shell can present the active whiteboard editor.
- App shell → Storage: persists · Shell coordinates reading and writing boards in browser storage.
- Dashboard → Storage: reads/writes · Dashboard manages the board list in LocalStorage.
- Whiteboard → Domain types: uses · Editor operates on the shared board and item model.
- Whiteboard → Constants: uses · Editor relies on shared tool and visual defaults.
- Whiteboard → Utils: uses · Editor uses geometry and interaction helpers.
- Whiteboard → Storage: saves · Board edits are serialized back to browser storage.
- Whiteboard → Item view: renders · Editor delegates per-item drawing to item views.
- Item view → Domain types: uses · Item renderer depends on item definitions.
- Item view → Constants: uses · Item renderer uses shared presentation defaults.
- Item view → Icons: uses · Item renderer may share iconography with the UI.
- Utils → Domain types: uses · Helper logic works over shared model types.
- Deploy workflow → Next config: builds with · Deployment uses the Next.js static export configuration.
- Deploy workflow → Smoke test: verifies · Workflow runs a post-build smoke test before deploy.
- Deploy workflow → .nojekyll: publishes · GitHub Pages deployment includes the nojekyll marker.
- Next config → Main page: exports · Static build includes the app routes and page entry.
