Skip to content

Developer Guide

This guide covers development setup and contribution guidelines for Mindwtr.


Product Philosophy

Mindwtr is built to be simple by default and powerful when you need it. We focus on reducing cognitive load, cutting the fat, and keeping users in flow. Every contribution is weighed against these tenets:

  • Progressive disclosure: advanced options stay hidden until they matter.
  • Less by default: fewer fields, fewer knobs, fewer distractions.
  • Avoid feature creep: we prioritize clarity over clutter.
  • Automatic beats manual: if the right outcome can be inferred or predicted — from the platform, the install channel, existing data, or context — the app should just do it. That applies everywhere, not only to settings: no knob to configure, no prompt asking what the app can answer itself, no extra tap or manual step in a workflow, no UI the user must operate to get the obvious result. Every manual step moves cognitive load from us (once) onto every user (forever). The update checker is the model: instead of a "disable update checks" toggle, the app detects how it was installed and behaves correctly per channel — package-manager installs go quiet on their own, with no setting shipped. When the right behavior genuinely can't be inferred and demand is real, gate the feature behind an existing switch or affordance before minting a new one.

Don't show me a cockpit when I just want to ride a bike.

See Engineering Principles for the data-safety and sync guardrails that sit underneath these.


Quick Start

bash
# Clone repository
git clone https://github.com/dongdongbh/Mindwtr.git
cd Mindwtr

# Install dependencies
bun install

# Run desktop app (dev mode)
bun desktop:dev

# Run mobile app
bun mobile:start

Prerequisites

All Platforms

  • Bun — Package manager and runtime
  • Node.js — JavaScript runtime (for some tools)
  • Git — Version control

Desktop Development

  • Rust — Required for Tauri

Linux (Arch):

bash
sudo pacman -S rust webkit2gtk-4.1 base-devel cmake alsa-lib libayatana-appindicator

Linux (Debian/Ubuntu):

bash
sudo apt install libwebkit2gtk-4.1-dev build-essential libssl-dev libgtk-3-dev \
  cmake perl libasound2-dev libayatana-appindicator3-dev
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

For minimal build environments (containers, Nix) the full native set beyond the WebKitGTK/GTK3 stack is: cmake plus a C/C++ toolchain with bindgen support (local Whisper transcription), perl (OpenSSL's build), ALSA headers (audio), and libayatana-appindicator (tray icon).

macOS:

bash
xcode-select --install
brew install rust

Windows: Install Rust and Visual Studio Build Tools.

Mobile Development

  • Expo Go app (for testing)
  • Android Studio (for emulator/device builds)
  • Xcode (for iOS development)

Project Structure

Mindwtr/
├── apps/
│   ├── cloud/             # Sync server (Bun)
│   ├── desktop/           # Tauri v2 + React + Vite
│   │   ├── src/           # React source
│   │   │   ├── components/
│   │   │   ├── contexts/
│   │   │   ├── lib/
│   │   │   └── App.tsx
│   │   ├── src-tauri/     # Rust backend
│   │   └── package.json
│   │
│   └── mobile/            # Expo + React Native
│       ├── app/           # Expo Router pages
│       ├── components/
│       ├── contexts/
│       ├── lib/
│       └── package.json

├── packages/
│   └── core/              # Shared business logic
│       └── src/
│           ├── store.ts   # Zustand store
│           ├── types.ts   # TypeScript types
│           ├── i18n/      # Translation loader and locales
│           └── ...

├── scripts/               # Utility scripts (CLI, API, release)
├── docs/                  # Repository-local docs: ADRs, release notes, contribution docs
├── wiki/                  # Retired GitHub Wiki landing page (points to the docs site)
├── .github/               # CI/CD workflows
└── package.json           # Monorepo root

The mindwtr-web/docs tree is the canonical source for public user and developer documentation and publishes to https://docs.mindwtr.app/. The app repository's docs/ directory contains engineering and release artifacts such as ADRs, contribution/process guides, and release notes.


Available Scripts

Root Level

CommandDescription
bun installInstall all dependencies
bun desktop:devRun desktop in dev mode
bun mobile:startStart Expo dev server
bun mobile:androidRun on Android
bun mobile:iosRun on iOS
bun run testRun all tests
bun mindwtr:cliRun CLI tool
bun mindwtr:apiRun local API server

Desktop (apps/desktop)

CommandDescription
bun devDev mode with hot reload
bun buildBuild for production
bun run testRun tests

Mobile (apps/mobile)

CommandDescription
bun startStart Expo server
bun androidRun on Android
bun iosRun on iOS
ARCHS=arm64-v8a bash ./scripts/android_build.shBuild Android APK

Cloud (apps/cloud)

CommandDescription
bun devRun sync server

Core (packages/core)

CommandDescription
bun run testRun unit tests
bun buildBuild package

Tech Stack

LayerDesktopMobileCloud
FrameworkReact + ViteReact Native + ExpoBun (Native HTTP)
StylingTailwind CSSNativeWind (Tailwind)N/A
StateZustand (shared)Zustand (shared)N/A
PlatformTauri v2 (Rust)Expo (iOS/Android)Bun
RouterInternal view stateExpo RouterN/A
LanguageTypeScriptTypeScriptTypeScript

Architecture Decisions

We track key technical decisions as ADRs under docs/adr/. See:

  • docs/adr/README.md

Current sync ADRs to know before changing merge or transport behavior:

  • ADR 0003 defines revision-aware sync metadata (rev, revBy) and deterministic tombstone-aware merge.
  • ADR 0007 defines the shipped live-wins rule for ambiguous delete-vs-live conflicts.
  • ADR 0008 records that Mindwtr intentionally stays on snapshot-based sync for now instead of adding a delta log.

Contributors should treat the snapshot transport as a deliberate product choice, not missing infrastructure. Revisit ADR 0008 only if snapshot files regularly exceed 5 MB, sync round-trips exceed 5 seconds on typical networks, or Mindwtr needs real-time multi-device streaming.


Development Workflow

Making Changes

  1. Create a feature branch
  2. Make changes in the relevant package
  3. Run tests: bun run test
  4. Test on desktop: bun desktop:dev
  5. Test on mobile: bun mobile:start
  6. Commit with descriptive message
  7. Open a pull request

When adding a new top-level entity type, update the full persistence and sync surface in the same change: core AppData types and normalization, desktop SQLite schema/storage round-trip tests, mobile SQLite schema/backup restore, cloud validation/normalization, MCP tools if exposed, and the Core API docs source at https://github.com/dongdongbh/mindwtr-web/tree/main/docs.

Code Style

  • TypeScript for all code
  • Functional React components
  • Named exports preferred
  • JSDoc comments for public APIs

Testing

bash
# Run all tests
bun run test

# Run desktop tests
cd apps/desktop && bun run test

# Run core tests
cd packages/core && bun run test

Building for Production

Desktop

bash
cd apps/desktop
bun run build
# Output: src-tauri/target/release/

Desktop (diagnostics build)

Release builds disable devtools by default. To enable diagnostics/devtools, build with the diagnostics feature and opt-in at runtime:

bash
cd apps/desktop
cargo tauri build --features diagnostics
MINDWTR_DIAGNOSTICS=1 ./src-tauri/target/release/mindwtr

Mobile (Android APK)

bash
cd apps/mobile
ARCHS=arm64-v8a bash ./scripts/android_build.sh

See Mobile Installation for detailed build instructions.


Architecture Overview

See Architecture for detailed technical design.

Key Concepts

  • Monorepo: Single repo with shared dependencies
  • Shared Core: Business logic in @mindwtr/core
  • Platform Apps: Desktop and Mobile use the shared core
  • Local Storage: Data persisted locally
  • Multiple Sync: File, WebDAV, or Cloud sync

CLI Tool

Command-line interface for scripting and automation:

bash
# Add a task
bun mindwtr:cli -- add "Call mom @phone #family"

# List active tasks
bun mindwtr:cli -- list

# List with filters
bun mindwtr:cli -- list --status next --query "due:<=7d"

# Read or update a task
bun mindwtr:cli -- get <taskId>
bun mindwtr:cli -- update <taskId> '{"status":"next"}'

# Complete a task
bun mindwtr:cli -- complete <taskId>

# Archive, delete, or restore
bun mindwtr:cli -- archive <taskId>
bun mindwtr:cli -- delete <taskId>
bun mindwtr:cli -- restore <taskId>

# Search
bun mindwtr:cli -- search "@work"

# List projects
bun mindwtr:cli -- projects

Options:

  • --data <path> — Override data.json location
  • --db <path> — Override mindwtr.db location
  • MINDWTR_DATA — Environment variable for data path
  • MINDWTR_DB_PATH — Environment variable for DB path

On desktop-compatible paths, the CLI keeps mindwtr.db and data.json aligned so changes remain visible before and after the app starts.


Local REST API

Run a local API server for scripting and integrations:

bash
# Start API server
bun mindwtr:api -- --port 4317

# With auth token
MINDWTR_API_TOKEN=secret bun mindwtr:api -- --port 4317

The local API uses the same storage contract as the CLI, keeping mindwtr.db and data.json in sync on desktop-compatible paths.

Endpoints

MethodEndpointDescription
GET/healthHealth check
GET/tasksList tasks
GET/tasks?status=nextFilter by status
GET/tasks?query=@workSearch tasks
POST/tasksCreate task
PATCH/tasks/:idUpdate task
DELETE/tasks/:idSoft delete task
POST/tasks/:id/completeMark task done
POST/tasks/:id/archiveMark task archived
POST/tasks/:id/restoreRestore deleted task
GET/projectsList projects
GET/search?query=...Search tasks+projects

Example:

bash
# Add task via API
curl -X POST http://localhost:4317/tasks \
  -H "Content-Type: application/json" \
  -d '{"input": "Review PR @work /due:tomorrow"}'

# Complete task
curl -X POST http://localhost:4317/tasks/<id>/complete

Cloud Server

Self-hosted cloud sync backend:

bash
# From monorepo root
bun run --filter mindwtr-cloud dev -- --port 8787

Endpoints

MethodEndpointDescription
GET/healthHealth check
HEAD/v1/dataGet snapshot metadata
GET/v1/dataGet user data
PUT/v1/dataMerge and save user data; returns merge stats
GET, POST/v1/tasksList or create tasks
GET, PATCH, DELETE/v1/tasks/:idRead, update, or soft-delete a task
POST/v1/tasks/:id/completeMark a task done
POST/v1/tasks/:id/archiveArchive a task
GET, POST/v1/projectsList or create projects
GET, PATCH, DELETE/v1/projects/:idRead, update, or soft-delete a project
GET, POST/v1/sectionsList or create sections
GET, PATCH, DELETE/v1/sections/:idRead, update, or soft-delete a section
GET, POST/v1/areasList or create areas
GET, PATCH, DELETE/v1/areas/:idRead, update, or soft-delete an area
GET/v1/searchSearch tasks and projects
GET, PUT, DELETE/v1/attachments/*Download, upload, or delete attachment files
POST, DELETE/v1/attachments/orphansScan or remove orphan attachment files

Authentication: Authorization: Bearer <token>

Each token gets its own data file (SHA-256 hashed filename).

Environment:

  • PORT — Server port (default 8787)
  • HOST — Bind address (default 0.0.0.0)
  • MINDWTR_CLOUD_DATA_DIR — Data directory

Web App (PWA)

Run the desktop UI in a browser with PWA support:

bash
# Development
bun desktop:web

# Production build
bun desktop:web:build

Uses localStorage for data storage and includes offline support via service worker.


See Also

Mindwtr is free, open source, and local-first.
Getting Things Done and GTD are registered trademarks of the David Allen Company. Mindwtr is not affiliated with, endorsed by, or sponsored by the David Allen Company.