Inspiration
As developers, we live by copy-paste. But the standard clipboard is a black hole, it only holds one item. We constantly lose useful code snippets, terminal commands, or URLs. We were inspired to build the clipboard manager we always wanted: one that not only remembers our history but also intelligently surfaces our most used items. We wanted a tool that felt like a native developer utility: fast, persistent, and built with a modern stack.
What it does
Clip-it is a persistent, cross-platform clipboard manager. It automatically monitors the system clipboard for new text and images, saving them to a local history.
It features:
Dual-Queue System: Users can toggle between "Most Recent" (LRU) for a chronological history and "Most Frequent" (LFU) to instantly find the items they copy all the time.
Persistent History: The entire clipboard store is saved to a clipboard_store.json file on every new copy and is automatically reloaded when the app starts.
Text and Image Support: Clip-it handles both text snippets and images seamlessly.
Instant Re-copy: Clicking any item in the list instantly copies it back to the clipboard.
Hover-to-Preview: To avoid visual clutter, users can hover over any item for one second to see a full-size preview popup.
History Flush: A "Flush" command in the status bar allows users to permanently delete the in-memory and on-disk history.
How we built it
Clip-it is built with Tauri, using a Rust backend and a React + TypeScript frontend.
Backend (Rust): We used Tauri's tauri-plugin-clipboard-manager to listen for clipboard changes in a background thread. The history is managed in a Mutex using two core data structures: an LruCache for chronological order and a HashMap for frequency counting (LFU). The serde and serde_json crates handle persisting the entire store to a file. We also use the sha2 crate to hash images for efficient de-duplication.
Frontend (React): The UI is built with React and Vite. We use Tauri's invoke API to call Rust functions (get_lru, get_lfu, flush_store). A unique feature is our image rendering: images are passed from Rust as Base64-encoded RGBA data, which we decode in React and draw onto a element for a pixel-perfect preview.
Challenges we ran into
Our biggest challenge was frontend performance. Our initial implementation had two major bugs that made buttons unclickable:
The entire app re-rendered on every single mouse movement (to track position for the hover popup).
The entire app re-rendered every single second (to update the status bar clock).
We solved this by memoizing the status bar with React.memo and useCallback, and by isolating the clock into its own separate component. This stopped the unnecessary re-renders and made the UI responsive.
We also spent significant time debugging the Rust environment, battling a corrupted Cargo cache that incorrectly reported the lru crate was missing its serde feature.
Accomplishments that we're proud of
We are most proud of diagnosing and fixing the React performance bottlenecks. Isolating the re-renders was a huge "a-ha!" moment. We're also proud of the efficient image handling, hashing in Rust and rendering on a in React is a fast and effective solution that we hadn't tried before. Finally, implementing both LRU and LFU stores gives the app a powerful "second brain" that simple clipboard managers lack.
What we learned
We learned a deep lesson in React performance: "if it's unclickable, check your re-renders." We now have a much better understanding of how state updates can ripple through an application and how to stop them with memoization. We also learned the fundamentals of the Tauri v2 plugin system and, critically, how to debug and force-clean a corrupted Cargo cache.
What's next for Clip-it
The immediate next step is full keyboard navigation, allowing users to select and copy items without touching the mouse. We also plan to add a "Favorites" or "Pinned" section for permanently saving important snippets. Longer-term, we want to implement a global hotkey (e.g., Cmd+Shift+V) to instantly summon the app.
Built With
- react
- rust
- tauri
- typescript
Log in or sign up for Devpost to join the conversation.