Skip to main content

Overview

Glyph is an offline-first desktop note-taking app built with a hybrid architecture:
  • Frontend: React 19 + TypeScript + Vite + Tailwind 4
  • Backend: Tauri 2 + Rust
  • Editor: TipTap (Markdown)
  • AI: Rig-backed multi-provider chat
  • UI: shadcn/ui + Radix UI + Motion
  • Storage: SQLite index + filesystem

Application Structure

Frontend (src/)

The frontend is a single-page React application with a context-based state management architecture.

Backend (src-tauri/src/)

The Rust backend handles all filesystem operations, indexing, and AI integration.

IPC Layer

Communication between frontend and backend uses typed Tauri commands.
1

Define Rust command

Implement command in src-tauri/src/ module
src-tauri/src/space/commands.rs
2

Register in lib.rs

Add to Tauri builder’s invoke handler
src-tauri/src/lib.rs
3

Add TypeScript types

Define in TauriCommands interface
src/lib/tauri.ts
4

Invoke from frontend

Always use typed invoke() wrapper

Data Flow

File Operations

Search Flow

State Management

React Context Architecture

Glyph uses no global state library (no Redux/Zustand). All state is managed via React Context with the following hierarchy:

File System Layout

Each space is a directory containing:
The .glyph/ folder stores derived data and can be safely deleted. It will be regenerated on next space open.

Build & Bundle

Development

  • pnpm dev - Vite dev server (frontend only)
  • pnpm tauri dev - Full Tauri app with hot reload

Production

  • pnpm build - TypeScript check + Vite build
  • pnpm tauri build - Create native app bundle
    • macOS: .dmg + .app
    • Windows: .msi + .exe
    • Linux: .deb + .AppImage

Security Architecture

Path Traversal Prevention

All space-relative paths are validated using paths::join_under():
src-tauri/src/paths.rs

SSRF Prevention

User-supplied URLs (link previews) are checked before fetching:
src-tauri/src/net.rs

Atomic Writes

All file writes use crash-safe atomic operations:
src-tauri/src/io_atomic.rs

Migration Policy

Glyph uses a hard cutover migration approach. When the space schema changes, old versions cannot open new spaces. Never implement backward compatibility.
Version is stored in space.json: