A creative and stylish clipboard manager built with Wails, designed to keep track of everything you copy through a clean, paper-aesthetic interface. It automatically records every clipboard change in real time, storing your copy history so you can easily revisit, reuse, and manage past content whenever you need it.
Windows 10/11 (64-bit) | Version 0.8.0
When running the app for the first time, Windows SmartScreen may show a warning because the app is not yet code-signed. This is normal for open-source applications.
To run the app:
- Click "More info" on the SmartScreen warning
- Click "Run anyway"
Or alternatively:
- Right-click the downloaded .exe file
- Select "Properties"
- Check "Unblock" at the bottom
- Click "Apply" then "OK"
- Run the executable
The app is safe and open source - you can verify the code yourself!
-
Automatic Clipboard Monitoring - Automatically captures everything you copy (text and images) in real time via a native Windows message-only window
-
Image Support - Captures and displays clipboard images, stored as BLOBs and rendered from base64 in the UI
-
Pin Important Clips - Keep your most-used clips anchored to the top; pinned clips are protected from automatic deletion when the storage limit is reached
-
-
Fast Search - Instantly filter all clips with
Ctrl+F; searches both pinned and recent clips simultaneously -
-
Unique Paper Aesthetic - Beautiful hand-drawn, notebook-style UI with GSAP animations, paper curtain reveals, and a soundtrack of satisfying sounds
-
Easy Management - Copy, pin, and delete clips with intuitive hover controls
-
Edit Clips - Modify the text content of any saved clip in-place without re-copying
-
Manual Clip Creation - Add new clips directly from the app without copying anything; supports pinning on creation
-
-
Privacy Mode - Instantly blur all clip content for privacy or screen sharing; toggle with
Alt+H -
-
-
Quick Paste - A power-user workflow mode. When enabled, Clipcat hides to the system tray. Press
Ctrl+Shift+Vfrom any window to summon it, click the paste icon on a clip, and it fires directly into the window you were just using -- then vanishes again. When disabled, the paste button still lets you fire any clip into your last focused window without hiding the app. -
-
System Tray - Clipcat lives in the system tray and can be summoned or quit from there at any time, even when the window is hidden
-
-
Global Hotkey -
Ctrl+Shift+Vis a system-wide hotkey that brings Clipcat to the front from any application -
Paste Into Any Window - Every text clip has a paste button that fires its content directly into whichever window you had focused before opening Clipcat. No manual copying needed -- the previous window is tracked automatically in the background
-
Blocked Apps - Add any
.exename (e.g.1password.exe) to a blocklist. Clipboard changes originating from those processes will be silently ignored and never stored -
-
Pause Capture - Temporarily suspend all clipboard monitoring without closing the app. Resume it any time from settings
-
-
Bulk Actions - Quickly delete all clips, only pinned clips, or only unpinned clips via the settings menu -- all with a confirmation dialog
-
-
-
Hyperlink Detection - URLs inside clip text are automatically rendered as clickable links that open in your default browser
-
Relative Timestamps - Each clip shows a live-updating relative time (e.g. "2 minutes ago", "yesterday")
-
Duplicate Detection - Automatically prevents saving duplicate text or image content
-
Sound Effects - Audible feedback for copy, paste, delete, pin, and settings interactions; can be toggled off with
Alt+S -
Persistent Storage - SQLite database keeps your clips safe across restarts
-
Configurable Storage Limit - Customize how many clips to keep (100-500, in steps of 50); pinned clips are always preserved regardless of the limit
-
-
Mini Clip Mode - A compact, always-on-top window for unobtrusive usage; toggle with
Alt+M -
-
Startup Support - Option to launch Clipcat automatically when your system starts
-
-
Auto Update Check - Automatically checks for new versions on GitHub
- Go - Core application logic
- Wails v2 - Desktop application framework
- SQLite (via modernc.org/sqlite) - Local database for clip storage
- golang.design/x/clipboard - Cross-platform clipboard access with image support
- lxn/win - Windows API bindings for the clipboard message window
- getlantern/systray - Cross-platform system tray icon and menu
- React 18 - UI framework
- TypeScript - Type-safe JavaScript
- Vite - Fast build tool and dev server
- Tailwind CSS - Utility-first CSS framework
- shadcn/ui - Accessible component library
- GSAP - Animation library
- Lucide React - Icon library
Clipcat uses Wails to:
- Integrate native Windows clipboard APIs via Go
- Communicate clipboard events to a React UI in real time
- Bundle a lightweight, native-feeling desktop app without Electron
Clipcat follows a clean architecture pattern with clear separation between frontend and backend:
+--------------------------------------------------+
| Frontend (React) |
| +------------+ +----------+ +-----------+ |
| | UI Layer | | Context | | Components| |
| | (TSX/CSS) | | Provider | | (Cards) | |
| +------------+ +----------+ +-----------+ |
+---------------------+----------------------------+
| Wails Bridge (IPC)
+---------------------+----------------------------+
| Backend (Go) |
| +----------+ +----------+ +--------------+ |
| | app.go | | clips.go | | settings.go | |
| | (Bridge) | | (Logic) | | (Prefs) | |
| +----------+ +----------+ +--------------+ |
| +----------+ +----------+ +--------------+ |
| | tray.go | | ignore.go| | db.go | |
| | (Tray) | | (Filter) | | (Storage) | |
| +----------+ +----------+ +--------------+ |
+---------------------+----------------------------+
|
+-----------+-----------+
| |
+-----+------+ +--------+--------+
| SQLite | | Windows API |
| Database | | (Clipboard + |
+------------+ | Hotkey + Focus)|
+-----------------+
-
Clipboard Monitoring
- A hidden
HWND_MESSAGEwindow receivesWM_CLIPBOARDUPDATEnotifications from Windows - A 150 ms debounce prevents duplicate saves when apps write the clipboard in multiple steps
- The ignore list filters out events from blocked processes before saving
- A hidden
-
Focus Tracking
- A background goroutine polls
GetForegroundWindowevery 150 ms - It continuously stores the last non-Clipcat window, so the paste button always has a valid target without requiring the hotkey to be pressed first
- A background goroutine polls
-
Data Storage
- New clips are saved to SQLite with duplicate detection (text and image)
- Automatic cleanup keeps only the most recent N clips, always preserving pinned ones
- App preferences (Quick Paste mode, storage limit, ignore list) are stored in the same database
-
Frontend Updates
- Backend emits
clipboard:changedevents when new content is saved - React context manages all clip state and settings
- UI automatically re-renders with new data
- Backend emits
-
User Actions
- Copy: Uses browser clipboard API
- Paste to window: Focuses the previously tracked window and simulates Ctrl+V
- Pin/Unpin: Toggles database flag, reorders UI
- Delete: Removes from database, refreshes list
- Search: Client-side filtering with instant results
Clipcat/
|-- app.go # Wails app struct, startup, exposed bindings
|-- clips.go # Clip CRUD operations
|-- db.go # Database initialization and migrations
|-- settings.go # App settings (Quick Paste mode)
|-- ignore.go # Blocked app list persistence
|-- tray.go # System tray icon and menu
|-- main.go # Wails runtime setup
|-- go.mod # Go dependencies
|-- wails.json # Wails configuration
|-- internal/
| `-- clipboard/
| |-- listener_window.go # Windows clipboard + hotkey listener
| `-- window_utils.go # Focus tracker, paste simulation, ignore check
|-- frontend/
| |-- src/
| | |-- App.tsx # Root component
| | |-- components/
| | | |-- page.tsx # Main page layout
| | | |-- clip-card.tsx # Individual clip card with all actions
| | | |-- window-controls.tsx # Title bar, settings panel
| | | |-- add-clip-dialog.tsx # Manual clip creation dialog
| | | |-- edit-clip-dialog.tsx# Clip edit dialog
| | | |-- delete-clips-dialog.tsx # Bulk delete dialog
| | | |-- about-dialog.tsx # About / version dialog
| | | `-- ui/ # shadcn/ui base components
| | |-- context/
| | | `-- ClipContext.tsx # Global state management
| | |-- helpers/
| | | |-- formatTime.ts # Date formatting
| | | |-- playSound.ts # Audio feedback
| | | |-- insertLinks.ts # URL to clickable link renderer
| | | |-- copyBase64Image.ts # Image clipboard helper
| | | `-- wait.ts # Promise-based delay
| | `-- types/
| | `-- clip.ts # TypeScript interfaces
| |-- wailsjs/ # Auto-generated Wails bindings
| |-- public/ # Static assets (sounds, images, cursors)
| |-- package.json
| `-- vite.config.ts
`-- build/ # Build configuration
`-- windows/
`-- installer/ # NSIS installer config
Clipboard Monitoring (internal/clipboard/listener_window.go)
A hidden HWND_MESSAGE window is registered with AddClipboardFormatListener. Windows delivers WM_CLIPBOARDUPDATE messages to it whenever any app writes to the clipboard. The same window also handles WM_HOTKEY for the global Ctrl+Shift+V shortcut via RegisterHotKey.
case WM_CLIPBOARDUPDATE:
// 150 ms debounce + pause check + ignore list check
// then calls onChangeCallback()
case WM_HOTKEY:
// Snapshot the current foreground window, then show Clipcat
capturePreviousWindow()
go onHotkeyCallback()Focus Tracking (internal/clipboard/window_utils.go)
A background goroutine polls GetForegroundWindow every 150 ms, skipping Clipcat's own process, so the paste target is always up to date:
func StartFocusTracker() {
go func() {
for {
time.Sleep(150 * time.Millisecond)
hwnd, _, _ := procGetForegroundWindow.Call()
// skip our own PID, then store prevHWND
}
}()
}Database Schema (db.go)
CREATE TABLE clips (
id INTEGER PRIMARY KEY AUTOINCREMENT,
content TEXT,
image BLOB,
type TEXT NOT NULL,
pinned BOOLEAN DEFAULT 0,
created_at DATETIME
);
CREATE TABLE clip_storage_limit (
id INTEGER PRIMARY KEY CHECK (id = 0),
limit_count INTEGER DEFAULT 100
);
CREATE TABLE ignore_list (
process_name TEXT PRIMARY KEY
);
CREATE TABLE settings (
id INTEGER PRIMARY KEY CHECK (id = 0),
ghost_mode INTEGER DEFAULT 0 -- 1 = Quick Paste enabled
);
contentis nullable to support image-only clips. Eithercontentorimageis populated based on the cliptype.
Key Operations (clips.go)
getClips()- Fetches all clips ordered by pinned status, then by dateclipExists()/imageClipExists()- Prevent duplicate text and image clipsaddClip()- Inserts new text clip and enforces storage limit (preserving pinned)addImageClip()- Inserts new image clip as BLOB and enforces storage limitaddManualClip()- Inserts a user-created clip with optional pinned flagtogglePinClip()- Toggles pinned status by IDdeleteClip()- Removes clip by IDdeleteAllClips()/deletePinnedClips()/deleteUnpinnedClips()- Bulk delete with native confirmation dialogupdateClipContent()- Edits text content of an existing clip
State Management (ClipContext.tsx)
- Global state with React Context
- Splits clips into
pinnedandrecentarrays - Listens for
clipboard:changedevents from backend - Manages all settings: sound, hide content, mini clip, startup, pause capture, blocked apps, Quick Paste
UI Components
- ClipCard - Individual clip with copy / paste-to-window / edit / pin / delete actions; renders text (with clickable links) or image; shows relative timestamps
- Page - Main layout with animated paper curtain reveal, search bar, pinned section, and recent section
- WindowControls - Frameless title bar with minimize/maximize/close and an animated settings panel
- AddClipDialog - Inline manual clip creation with optional pinning
- EditClipDialog - Edit existing clip content in a modal
- DeleteClipsDialog - Bulk delete options (all / pinned / unpinned)
- AboutDialog - App info with automatic GitHub update checking
Animations (GSAP)
- Paper curtain reveal and cat character entrance on startup
- Settings panel slide/scale in and out
- Clip card row-span masonry layout
- Privacy mode cat swap
- Sound effects on every interaction
- Go 1.24.0 or higher
- Node.js 18+ and npm
- Wails CLI:
go install github.com/wailsapp/wails/v2/cmd/wails@latest
-
Clone the repository
git clone https://github.com/d3uceY/clipcat.git cd clipcat -
Install dependencies
# Backend dependencies go mod download # Frontend dependencies cd frontend npm install cd ..
-
Run in development mode
wails dev
The app will launch with hot-reload enabled for both frontend and backend.
Development Build
wails buildProduction Build with NSIS Installer (Windows)
wails build -nsisThe built application will be in build/bin/.
Clips are stored in a SQLite database at:
Windows: %APPDATA%\clipussy\db\gyatt.db
| Shortcut | Action |
|---|---|
Ctrl + Shift + V |
Summon / show Clipcat from any application (system-wide) |
Ctrl + F |
Focus the search bar |
Alt + M |
Toggle Mini Clip mode |
Alt + H |
Toggle Privacy Mode (hide content) |
Alt + S |
Toggle sound effects |
The storage limit is dynamic and stored in the database. Adjust it in the settings panel (100-500, steps of 50) or programmatically:
import { GetStorageLimit, UpdateStorageLimit } from './wailsjs/go/main/App'
const limit = await GetStorageLimit()
await UpdateStorageLimit(200)Or directly in the database:
INSERT OR REPLACE INTO clip_storage_limit (id, limit_count) VALUES (0, 200);Add its process name in the "Blocked Apps" settings panel, or directly:
INSERT OR IGNORE INTO ignore_list (process_name) VALUES ('1password.exe');Edit the volume argument in component handlers:
playSound("/sounds/file.mp3", soundOn, 0.3) // 0.0 to 1.0Edit frontend/src/index.css and Tailwind classes in components.
Contributions are welcome! Feel free to submit issues and pull requests.
Onyekwelu Jesse (@d3uceY)
This project is licensed under the MIT License.
- Wails for the amazing Go + Web framework
- All open-source contributors whose libraries made this possible
Made with love by d3uceY
