Skip to content

Project Setup

This page covers everything you need to start developing Diagrammer locally.

Prerequisites

  1. Bun — JavaScript runtime and package manager (bun.sh)
  2. Rust toolchain — via rustup (stable channel)
  3. Platform dependencies — see Tauri v2 prerequisites
  4. Task (optional) — task runner (taskfile.dev) for convenient commands
Linux (Debian/Ubuntu)
bash
# System dependencies for Tauri
sudo apt-get update
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev \
  librsvg2-dev patchelf
macOS
bash
# Xcode command line tools (provides system headers)
xcode-select --install
Windows

Install the Desktop development with C++ workload from Visual Studio Build Tools.

Getting the Code

bash
git clone https://github.com/QR-Madness/diagrammer.git
cd diagrammer
bun install

Development Commands

CommandDescription
bun run devStart Vite dev server (web only)
bun run tauri:devStart Tauri desktop app with hot-reload
bun run typecheckRun TypeScript type checking
bun run testRun Vitest in watch mode
bun run test --runRun all tests once
bun run buildProduction web build
bun run tauri:buildBuild desktop installer
task checkRun typecheck + all tests (requires Task)

Rust Backend

bash
# Type-check the Rust backend
cargo check --manifest-path src-tauri/Cargo.toml

# Run Rust tests
cargo test --manifest-path src-tauri/Cargo.toml

Project Layout

diagrammer/
├── src/                    # TypeScript source
│   ├── math/               # Vec2, Mat3, Box, geometry utilities
│   ├── engine/             # Camera, Renderer, InputHandler, SpatialIndex
│   ├── store/              # Zustand stores (Document, Session, History…)
│   ├── shapes/             # Shape handlers and libraries
│   ├── collaboration/      # Protocol, sync providers, offline queue
│   ├── storage/            # BlobStorage, TeamDocumentCache, TrashStorage
│   ├── ui/                 # React components (Toolbar, PropertyPanel…)
│   ├── tauri/              # Tauri command bindings
│   └── plugins/            # Panel extension registry
├── src-tauri/              # Rust backend
│   ├── src/
│   │   ├── lib.rs          # Tauri commands, docs server, window setup
│   │   └── server/         # WebSocket server, protocol, auth
│   ├── Cargo.toml
│   └── tauri.conf.json     # Tauri build and window config
├── docs-site/              # VitePress documentation site
├── vite.config.ts          # Vite + Vitest config
├── tsconfig.json           # TypeScript config (strict mode)
└── Taskfile.yml            # Task runner definitions

TypeScript Configuration

The project uses strict TypeScript with additional flags beyond strict: true:

FlagEffect
noUncheckedIndexedAccessIndex access returns T | undefined
exactOptionalPropertyTypesOptional properties require explicit undefined
noPropertyAccessFromIndexSignatureForces bracket notation for index signatures
noUnusedLocals / noUnusedParametersUnused variables are errors
noImplicitReturnsAll code paths must return

The path alias @/* maps to ./src/* and is configured in both tsconfig.json and vite.config.ts.

Testing

Tests use Vitest with jsdom environment. Test globals (describe, it, expect) are available without imports. Test files live alongside source code with .test.ts suffix.

bash
# Run a single test file
bun run test src/engine/Camera.test.ts

# Run tests with browser UI
bun run test:ui
ModuleCoverage
/src/math/Vec2, Mat3, Box, geometry — 204 tests
/src/engine/Camera, InputHandler, Renderer, SpatialIndex, HitTester
/src/store/DocumentStore, SessionStore, PageStore, HistoryStore
/src/shapes/Shape handlers, bounds, transforms
/src/collaboration/Protocol, sync providers, offline queue

TIP

Run task check to typecheck and test in one command — this is what CI runs.