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.7.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" β "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)
-
Image Support - Captures and displays clipboard images with base64 encoding
-
Pin Important Clips - Keep your most-used clips at the top
-
-
Fast Search - Quickly find clips with Ctrl+F
-
-
Unique Paper Aesthetic - Beautiful hand-drawn, notebook-style UI
-
Easy Management - Copy, pin, and delete clips with intuitive controls
-
Edit Clips - Modify the content of your saved clips anytime
-
Manual Creation - Add new clips directly from the app without copying
-
-
Privacy Mode - Instantly hide clip content for privacy or during screen sharing
-
-
-
Bulk Actions - Quickly delete all, recent, or pinned clips via the settings menu
-
-
-
Full Content View - Click any clip to view complete content in a scrollable dialog
-
-
Duplicate Detection - Automatically prevents saving duplicate clipboard content
-
Sound Effects - Audible feedback for actions
-
Persistent Storage - SQLite database keeps your clips safe
-
Configurable Storage Limit - Customize how many clips to keep (default: 100)
-
-
Mini Clip Mode - A compact, always-on-top window for unobtrusive usage
-
-
Startup Support - Option to launch 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
- Windows API (lxn/win) - Native Windows clipboard monitoring
- 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 β β db.go β β
β β (Bridge) β β (Logic) β β(Storage) β β
β ββββββββββββββ ββββββββββββ ββββββββββββ β
ββββββββββββββββββββββββ¬βββββββββββββββββββββββββββ
β
ββββββββββββββ΄βββββββββββββ
β β
βββββββΌββββββ ββββββββββΌβββββββββ
β SQLite β β OS Clipboard β
β Database β β Listener β
βββββββββββββ βββββββββββββββββββ
-
Clipboard Monitoring
- Windows clipboard listener runs in the background
- Detects clipboard changes via Windows API
- Filters out duplicate or empty content
-
Data Storage
- New clips are saved to SQLite database
- Automatic cleanup keeps only 100 most recent clips (prioritizing pinned)
- Each clip stores: content, type, timestamp, and pinned status
-
Frontend Updates
- Backend emits events when clipboard changes
- React context manages clip state
- UI automatically re-renders with new data
-
User Actions
- Copy: Uses browser clipboard API
- Pin/Unpin: Toggles database flag, reorders UI
- Delete: Removes from database, refreshes list
- Search: Client-side filtering with instant results
Clipcat/
βββ app.go # Main application entry point
βββ clips.go # Clip CRUD operations
βββ db.go # Database initialization
βββ main.go # Wails runtime setup
βββ go.mod # Go dependencies
βββ wails.json # Wails configuration
βββ internal/
β βββ clipboard/
β βββ listener_window.go # Windows clipboard listener
βββ frontend/
β βββ src/
β β βββ App.tsx # Root component
β β βββ components/
β β β βββ page.tsx # Main page layout
β β β βββ ui/
β β β βββ clip-card.tsx # Individual clip card
β β β βββ dialog.tsx # Modal dialog
β β βββ context/
β β β βββ ClipContext.tsx # Global state management
β β βββ helpers/
β β β βββ formatTime.ts # Date formatting
β β β βββ playSound.ts # Audio feedback
β β βββ types/
β β βββ clip.ts # TypeScript interfaces
β βββ wailsjs/ # Auto-generated Wails bindings
β βββ public/ # Static assets
β βββ package.json
β βββ vite.config.ts
βββ build/ # Build configuration
βββ windows/
βββ installer/ # NSIS installer config
Clipboard Monitoring (internal/clipboard/listener_window.go)
// Polls clipboard every 500ms using Windows API
// Compares clipboard sequence numbers to detect changes
// Invokes callback when new content is detectedDatabase 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
);Note: The content field is nullable to support image-only clips. Either content or image will be populated based on the clip type.
Key Operations (clips.go)
getClips()- Fetches all clips ordered by pinned status, then by dateclipExists()- Checks if content already exists to prevent duplicates (text only)addClip()- Inserts new text clip (skips duplicates) and maintains dynamic clip limitaddImageClip()- Inserts new image clip as BLOB and maintains dynamic clip limittogglePinClip()- Toggles pinned status by IDdeleteClip()- Removes clip from databasegetStorageLimit()- Retrieves current storage limit from databaseupdateStorageLimit()- Updates the maximum number of clips to store
State Management (ClipContext.tsx)
- Global state using React Context API
- Splits clips into pinned and recent arrays
- Listens for clipboard events from backend
- Provides
getClips()method for manual refresh
UI Components
- ClipCard - Individual clip with copy/pin/delete actions; displays text or image based on type
- Page - Main layout with search, pinned section, recent section
- AboutDialog - Modal with app information and automatic update checking
Animations (GSAP)
- Paper curtain reveal on startup
- Cat character entrance
- Info button nudge animation
- Sound effects on interactions
- 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
Ctrl + F- Focus search barCtrl + C- Copy selected text (triggers clipboard monitoring)
The storage limit is now dynamic and stored in the database. You can update it programmatically:
From Frontend:
import { GetStorageLimit, UpdateStorageLimit } from './wailsjs/go/main/App'
// Get current limit
const limit = await GetStorageLimit()
// Set new limit
await UpdateStorageLimit(200)Or manually in the database:
INSERT OR REPLACE INTO clip_storage_limit (id, limit_count) VALUES (0, 200);Edit respective handlers in clip-card.tsx and page.tsx:
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 π by d3uceY
