A beautiful clipboard history manager for Windows, built with Rust + Tauri + React + TypeScript.
Also available for macOS on the App Store — visit pastepaw.com for more.



winget install XueshiQiao.PastePaw
Download the latest installer directly from: https://github.com/XueshiQiao/PastePaw/releases
🔍 Security: Every release is automatically scanned with VirusTotal (70+ antivirus engines). Scan results are linked at the bottom of each release note.
Ctrl+Shift+V (Default, Customizable in Settings)Ctrl + F - Focus searchEscape - Close window / Clear searchEnter - Paste selected itemDelete - Delete selected itemP - Pin/Unpin selected itemArrow Up/Down - Navigate itemsPastePaw allows you to exclude specific applications from being recorded in the clipboard history. This is useful for privacy-sensitive applications like password managers or banking apps.
(You need to provide the API Key for the AI provider)
Logic & Behavior:
- How to manage: Go to Settings -> Ignored Applications. You can browse for an executable (.exe) or strictly type its name.
- Privacy Protection: When content is copied, PastePaw checks the source application against your ignore list.
- Robust Matching: The system checks against both:
1. Executable Name (e.g., notepad.exe) - Matches any instance of this app regardless of location.
2. Full File Path (e.g., C:\Windows\System32\notepad.exe) - Matches only the specific installed instance.
- Case Insensitive: Matching is case-insensitive to ensure reliable detection on Windows.
PastePaw integrates powerful AI capabilities to help you process your clipboard content more efficiently.
# Install dependencies
pnpm install
# Install Tauri CLI
cargo install tauri-cli
# Run development build
pnpm tauri dev
# Build for production
pnpm tauri build
PastePaw/
├── src-tauri/ # Rust backend
│ ├── src/
│ │ ├── main.rs # App entry point
│ │ ├── lib.rs # Core logic
│ │ ├── clipboard.rs # Clipboard monitoring
│ │ ├── database.rs # SQLite operations
│ │ ├── commands.rs # Tauri IPC commands
│ │ └── models.rs # Data models
│ └── Cargo.toml
├── frontend/ # React frontend
│ ├── src/
│ │ ├── components/ # UI components
│ │ ├── hooks/ # React hooks
│ │ ├── types/ # TypeScript types
│ │ └── App.tsx
│ └── package.json
└── README.md
Tauri v2 enforces a strict case mapping between JavaScript/TypeScript and Rust:
camelCase for argument names in invoke calls (e.g., filterId).snake_case for function arguments in #[tauri::command] (e.g., filter_id).Example:
* Frontend: invoke('get_clips', { filterId: 'pinned' })
* Backend: pub fn get_clips(filter_id: Option<String>)
Failure to follow this convention (e.g., passing snake_case from the frontend) will result in arguments being passed as null or None to the backend.
The application is designed to appear on the active monitor (the one containing the mouse cursor) whenever the global hotkey is pressed.
Detection Logic:
src-tauri/src/lib.rs (animate_window_show).GetCursorPos (via the windows crate) to determine the global mouse coordinates.window.available_monitors() to find the monitor whose bounds contain the cursor point.window.current_monitor().Positioning:
The application uses a centralized layout system to ensure the native window and the virtualized list remain synchronized.
src-tauri/src/constants.rs (Controls the OS window size).frontend/src/constants.ts (Controls UI rendering and math).The card height is dynamic and fills the available window space. To change it:
1. Update WINDOW_HEIGHT in both constants.rs and constants.ts to the same value.
2. Restart the application (required for Rust changes).
To add more or less space at the top/bottom of the cards (e.g., to prevent clipping during hover):
1. Modify CARD_VERTICAL_PADDING in frontend/src/constants.ts.
2. Increasing this value makes cards shorter; decreasing it makes them taller.
We use a Hybrid Clipboard Approach to solve the notorious Windows OSError 1418 (Thread does not have a clipboard open).
navigator.clipboard.write.Our Solution:
1. Frontend: Writes the Image Blob directly to the system clipboard.
2. Backend: Updates the internal database and triggers the paste shortcut (Shift+Insert).
Shift+Insert for Pasting?We use Shift + Insert as the default paste trigger instead of Ctrl + V.
Ctrl+V often fails in terminal emulators (PowerShell, WSL, VS Code Terminal), sending a control character instead of pasting.Shift+Insert is the universal paste standard recognized by virtually all Windows applications, including terminals and legacy software.sequenceDiagram
actor User
participant FE as Frontend (React/App.tsx)
participant BE as Backend (Rust/commands.rs)
participant BROWSER as WebView2 Clipboard API
participant OS as OS / Target App
User->>FE: Double click image clip
activate FE
FE->>BE: invoke('get_clip_detail', { id })
BE-->>FE: Full image (base64)
FE->>FE: base64ToBlob(...)
FE->>BROWSER: navigator.clipboard.write([ClipboardItem])
BROWSER->>OS: Clipboard image data set
FE->>BE: invoke('paste_clip', { id })
deactivate FE
activate BE
BE->>BE: Update clip timestamp/LRU
Note over BE: On Windows, backend does not rewrite image bytes
BE->>OS: Hide window
BE->>OS: Send Shift+Insert (when auto-paste is enabled)
deactivate BE
OS->>User: Pasted image appears
$ claude mcp add PastePaw \
-- python -m otcore.mcp_server <graph>