Development Workflow
Starting the App
pnpm tauri:devThis runs cargo tauri dev which starts two processes:
Vite dev server — Serves the React frontend on
http:with hot module replacement (HMR)/ / localhost: 37461 Rust compilation + app launch — Compiles the Rust backend and opens the native window
The WebView loads from the Vite dev server, so frontend changes appear instantly without restarting the app. Rust backend changes trigger a recompile and app restart automatically.
Building for Production
pnpm tauri:buildThis runs bash scripts/, which builds ROOT (zudotext.app) as a thin launcher — a KB-scale stub plus the shared core dylib. See the Build & Deploy page for the full pipeline.
Writing App Dev Entry
The WRITING app dev entry (tauri.conf.writing.json) is the renderer both ROOT and every LEAF embed. It is used for isolated frontend work without ROOT mode:
pnpm writing:dev # dev server for the writing renderer
pnpm writing:build # production build of the writing rendererAdmin Renderer
The admin renderer (renderer-admin/) is a separate Vite app for developer tools:
pnpm dev:admin # start the admin renderer dev serverUI Component Development
pnpm storybookOpens Storybook on port 6006 for developing and testing UI components in isolation. The @takazudo/ui-components package contains shared components (DraftBar, MergeToolbar, DiffViewerDialog, FontPicker, ChordIndicator, PanelDivider, PageLayout, Toast, FileTree, etc.) with stories.
Storybook uses @storybook/react-vite — the same Vite setup as the main app.
Linting and Formatting
pnpm checkRuns linting across the project. Markdown files (.md, .mdx) are formatted with @takazudo/mdx-formatter via lint-staged on commit.
Dev Mode Comparison
The project supports three development modes. Choose the one that best fits your task:
| Mode | Command | Backend | Browser DevTools | Real Data |
|---|---|---|---|---|
| Tauri | pnpm tauri:dev | Rust (IPC) | Limited (WebView) | Yes |
| Mock | pnpm dev:mock | In-memory JS | Full | Sample only |
| REST | pnpm dev:rest | Rust (HTTP) | Full | Yes |
Mock Dev Mode (Frontend-Only)
To work on the frontend without the Rust/Tauri backend:
pnpm dev:mockThis starts a standalone Vite dev server on port 1421 using a separate entry point (renderer/) and config (vite.config.mock.ts). The app runs entirely in the browser with an in-memory MockAdapter replacing the real Tauri backend.
What Works
Full UI — all pages, navigation, sidebar, drafts, editor, markdown preview
Settings — loads default settings from
@takazudo/app-defaultsArchives — mock message list with sample data
Pins — mock pin directories with sample entries
Draft editing — in-memory read/write
Keyboard shortcuts and command palette
What Does Not Work
Native dialogs —
dialog.openDirectory()returnsnullFile watchers — No filesystem events; use
MockControlsto manually trigger change events
When to Use
UI iteration and CSS tweaking
Component development and layout changes
Frontend-only debugging
Rapid prototyping without waiting for Rust compilation
Visual Indicator
A yellow MOCK badge appears in the bottom-right corner of the window to distinguish mock mode from the real app. The badge is non-interactive and always on top.
REST Dev Mode (Chrome + Real Backend)
To run the frontend in a regular browser with the full Rust backend over HTTP:
pnpm dev:restThis starts a Vite dev server on port 1422 using a separate entry point (renderer/) and config (vite.config.rest.ts). The app runs in Chrome and communicates with the Rust backend via HTTP requests and Server-Sent Events (SSE) instead of Tauri IPC.
Prerequisites
The Rust backend must be running. cargo tauri dev starts both the Tauri app and an axum HTTP server on port 3001. The REST dev mode frontend connects to this HTTP server.
# Shell 1 — start the backend (also opens the Tauri app)
pnpm tauri:dev
# Shell 2 — start the REST frontend in Chrome
pnpm dev:restHow It Works
The RestAdapter implements the same BackendAPI interface as the TauriAdapter and MockAdapter. Instead of Tauri's invoke() for commands and listen() for events, the REST adapter uses:
fetch()— for command calls (maps to axum HTTP endpoints on port 3001)SSE (Server-Sent Events) — for real-time events such as file-change notifications
Because the adapter implements the same interface, all existing UI code works without modification.
What Works
The same cloud workspace model as Tauri mode, plus supported local-only file operations and real settings
Full Chrome DevTools — network tab, performance profiler, accessibility inspector
Hot module replacement via Vite
What Does Not Work
Native dialogs — Browser cannot invoke macOS native dialogs
Some window-level features — Anything that requires the Tauri window API
When to Use
Debugging real backend behavior with full browser DevTools
Network inspection — see every backend call in the Chrome network tab
Performance profiling with Chrome's built-in profiler
Testing with real data and real file system operations
Accessibility auditing with browser extensions
Visual Indicator
A blue REST badge appears in the bottom-right corner of the window to distinguish REST mode from the Tauri app and mock mode.
Documentation Site
# Start dev server (Astro 6 / zudo-doc)
pnpm start
# Build
pnpm buildOther Tools
# CSS playground for experimenting with styles
pnpm playground
# Generate a new app instance (bind to a workspace, or run cloud genesis)
pnpm generate --help