Skip to main content

Overview

Scratch is built as a cross-platform desktop application using a modern hybrid architecture that combines the performance and security of Rust with the flexibility of web technologies.

Tech Stack

Backend (Rust)

  • Tauri v2 - Cross-platform desktop framework providing native OS integration
  • Tantivy - High-performance full-text search engine for note indexing
  • notify - File system watcher with custom debouncing logic
  • tokio - Async runtime for non-blocking I/O operations
  • serde/serde_json - Serialization for data exchange with frontend

Frontend (TypeScript/React)

  • React 19 - UI library with modern concurrent features
  • TypeScript - Type-safe development experience
  • TipTap - Extensible WYSIWYG editor built on ProseMirror
  • Tailwind CSS v4 - Utility-first styling framework
  • Vite - Fast build tool and dev server

Architecture Diagram

┌─────────────────────────────────────────────────────┐
│                   Frontend (React)                  │
│  ┌──────────────┐  ┌──────────────┐  ┌───────────┐ │
│  │   TipTap     │  │   Context    │  │    UI     │ │
│  │   Editor     │  │  Providers   │  │ Components│ │
│  └──────────────┘  └──────────────┘  └───────────┘ │
└─────────────────────────────────────────────────────┘

                         │ Tauri Commands (IPC)

┌─────────────────────────────────────────────────────┐
│                 Backend (Rust/Tauri)                │
│  ┌──────────────┐  ┌──────────────┐  ┌───────────┐ │
│  │   Tantivy    │  │    notify    │  │    Git    │ │
│  │    Search    │  │ File Watcher │  │    CLI    │ │
│  └──────────────┘  └──────────────┘  └───────────┘ │
└─────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────┐
│               File System (Markdown)                │
│         User-selected notes folder + .scratch/      │
└─────────────────────────────────────────────────────┘

Key Components

State Management

Scratch uses React Context for state management with a dual-context pattern for performance optimization:
  • NotesContext - Manages note CRUD operations, search, and file watching
    • Data context: notes, selectedNoteId, currentNote, searchResults
    • Actions context: selectNote, createNote, saveNote, deleteNote, search
    • Race condition protection during note switches
    • Recently saved note tracking to ignore own file watcher events
  • ThemeContext - Handles theme mode, typography, text direction, and page width
    • Applies CSS variables for dynamic theming
    • Persists settings to .scratch/settings.json
  • GitContext - Git operations with loading states and error handling
    • Auto-refresh status on file changes (1000ms debounce)

TipTap Editor

The editor is built with TipTap and includes custom extensions: Core Extensions:
  • StarterKit (basic formatting)
  • Markdown (bidirectional conversion)
  • Link, Image, TaskList, TaskItem, Table
  • Placeholder text
Custom Features:
  • Auto-save with 300ms debounce
  • Inline link editor popup (Cmd+K)
  • Slash commands (/) for quick block insertion
  • Markdown source mode toggle
  • Focus mode with animated transitions
  • Format bar with 13 formatting tools
  • Copy & Export menu (Markdown/Plain Text/HTML/PDF)
  • Find in note with highlighting
  • External file change detection

Tauri Commands (IPC)

All backend operations use Tauri’s command system for type-safe IPC: Note Management:
  • list_notes - Retrieve all notes with metadata
  • read_note - Load note content by ID
  • save_note - Persist note changes to disk
  • delete_note - Remove note file
  • create_note - Create new markdown file
Configuration:
  • get_notes_folder - Get current notes directory path
  • set_notes_folder - Change notes directory
  • get_settings - Load per-folder settings
  • update_settings - Save settings changes
Search:
  • search_notes - Full-text search via Tantivy
  • rebuild_search_index - Recreate search index
File Watching:
  • start_file_watcher - Monitor notes folder for external changes
Git Integration:
  • git_is_available - Check if git is installed
  • git_get_status - Get repository status
  • git_init_repo - Initialize git repository
  • git_commit - Create commit
  • git_push - Push to remote
  • git_add_remote - Add remote repository
  • git_push_with_upstream - Push with upstream tracking
Utilities:
  • copy_to_clipboard - System clipboard integration
  • copy_image_to_assets - Copy images to notes folder
  • save_clipboard_image - Save clipboard image to disk
  • open_folder_dialog - Native folder picker
  • reveal_in_file_manager - Show file in system explorer
  • open_url_safe - Open URLs with scheme validation

Search Implementation

Scratch uses Tantivy, a Rust full-text search engine:
  • Schema: id (string), title (text), content (text), modified (i64)
  • Query strategy: Full-text search with prefix query fallback (query*)
  • Results: Top 20 results with relevance scoring
  • Fallback: Cache-based search if Tantivy fails
The search index is stored in .scratch/search_index/ within the notes folder.

File Watching

The notify crate monitors the notes folder for external changes:
  • Debouncing: 500ms per file to batch rapid changes
  • Events: Emits “file-change” events to frontend via Tauri events
  • Conflict prevention: Frontend filters events for currently edited note
  • Cleanup: Debounce map retention for 5 seconds
This enables collaboration with AI agents and external editors.

Data Storage

Notes:
  • Stored as .md files in user-selected folder
  • Filenames derived from note title (sanitized)
  • First # Heading becomes the note title
Configuration:
  • App config: {APP_DATA}/config.json (notes folder path)
  • Per-folder settings: {NOTES_FOLDER}/.scratch/settings.json
  • Search index: {NOTES_FOLDER}/.scratch/search_index/
Settings Schema:
{
  "theme": "light" | "dark" | "system",
  "editorFont": "system" | "serif" | "mono",
  "editorFontSize": 16,
  "editorLineHeight": 1.6,
  "editorBoldWeight": 600,
  "textDirection": "ltr" | "rtl",
  "pageWidth": "narrow" | "normal" | "wide" | "full",
  "git": { "enabled": true, "autoCommit": false }
}

Permissions Model

Tauri v2 uses capability-based permissions defined in src-tauri/capabilities/default.json:
  • File system read/write for notes folder
  • Dialog (folder picker)
  • Clipboard access
  • Shell (for git commands)
  • Window management
  • Network (for auto-updater)
  • Single instance enforcement

Performance Optimizations

Scratch is designed to be 5-10x smaller and faster than alternatives like Obsidian.
Debouncing strategies:
  • Auto-save: 300ms
  • Search: 150ms
  • File watcher: 500ms per file
  • Git status refresh: 1000ms
React optimizations:
  • React.memo for expensive components (NoteList items)
  • useCallback/useMemo for performance-critical paths
  • Dual context pattern to prevent unnecessary re-renders
Async operations:
  • All I/O operations use tokio async runtime
  • Non-blocking file operations
  • Concurrent search index updates

Platform-Specific Features

macOS:
  • Native drag region for window controls
  • Code-signed and notarized binaries
  • Universal binary (arm64 + x86_64)
Windows:
  • WebView2 integration
  • NSIS installer
Linux:
  • AppImage and .deb packages
  • Multiple desktop environment support

Build docs developers (and LLMs) love