A clipboard manager for Windows, macOS and Linux. It keeps a searchable history of what you copy, pastes any recent entry with Ctrl+Shift+V and a number key, and has notes next to your history. With an optional account, history and notes sync to your other computers and can be shared with other people in spaces. Everything that syncs is end-to-end encrypted: the server stores it and relays it, but cannot read it.
It works offline and without an account. Sync and spaces are the only parts that need one.
Download the latest build from the releases page:
- Windows 10 or 11: the file ending in
-setup.exe. It installs for your user only, without admin rights. - Linux:
.deb. X11 works best; Wayland needs one setup step for the hotkeys, described in the Linux notes.
The app updates itself from the same releases page. On a Mac, pick the .dmg for your chip.
Then follow Install and first run: in about five minutes you copy three things, paste one by its number, and pin it. The full user guide is at orange-copy-paste-app.pages.dev/docs.
This repository is the desktop app and the workspace for the whole product. The sync server and the website have their own repositories, cloned into this folder beside the app.
| Component | What it is | Stack |
|---|---|---|
orange-copy-paste-clipboard-app-rust/ |
The desktop app: clipboard capture, history, notes, the sharing screens, and all encryption | React 19 and TypeScript with Vite, on Tauri 2 and Rust |
orange-copy-paste-clipboard-backend/ |
The sync server: encrypted storage, live updates between devices, sharing, file storage | Python 3.14 and FastAPI, Supabase Postgres and Auth, Redis, S3 or R2 |
orange-copy-paste-clipboard-website/ |
The public site: the user guide, the developer docs, and the landing page | Astro and Starlight, Bun |
Each component has its own README with setup and development instructions.
flowchart TB
subgraph A["Device A"]
A1["Desktop app<br/>local store<br/>sync engine"]
end
subgraph B["Device B"]
B1["Desktop app<br/>local store<br/>sync engine"]
end
BE["Sync server<br/>stateless, can run as several copies<br/>Supabase (Postgres + Auth), Redis, S3 / R2"]
A1 -- "HTTPS / WSS" --> BE
B1 -- "HTTPS / WSS" --> BE
classDef device fill:#1b1b1b,stroke:#9a9a9a,stroke-width:1.5px,color:#fafafa
classDef backend fill:#20140f,stroke:#ff3e1c,stroke-width:2px,color:#fafafa
class A1,B1 device
class BE backend
style A fill:#161616,stroke:#6f6f6f,color:#e4e4e4
style B fill:#161616,stroke:#6f6f6f,color:#e4e4e4
The app is the source of truth for your data. It captures the clipboard, stores history and notes on the computer, holds every key, and does all encryption and decryption. Rust owns the encryption and the sync engine; React is only the interface.
The server is a relay and a store. It checks the sign-in tokens Supabase issues (it never issues one itself), stores encrypted items, sends changes to other devices over a WebSocket, and hands out upload and download links for files. It defines the contract between app and server, and nothing else.
Sync is optional. With sync off or the server unreachable, the app works fully; changes queue on the computer and upload when it reconnects.
- The app signs in with Supabase Auth directly. Your password never leaves the computer: the app derives a separate login key from it, and a second key that stays behind.
- The app fetches your encrypted master key from the server and opens it with the key that stayed behind.
- It registers this computer as a device.
- Items are encrypted on the computer, then pushed and pulled. When two edits collide, the newest wins.
- A WebSocket brings live changes from your other devices and from your spaces.
Deletes travel as markers on the item, not as a delete request, so a delete reaches devices that were offline. Sharing has one building block, the space: live, any number of members, and a person can be in several. Each space has its own random key, locked separately for each member.
Exact routes, payloads, event names and key derivation are in the server's architecture doc, which owns the contract. What the server can and cannot see is in the security model.
RoverTools-Orange-Copy-Paste-App/
|- orange-copy-paste-clipboard-app-rust/ the desktop app (part of this repo)
|- orange-copy-paste-clipboard-backend/ own repo: RoverTools-Orange-Copy-Paste-Backend (git-ignored here)
|- orange-copy-paste-clipboard-website/ own repo: RoverTools-Orange-Copy-Paste-Website (git-ignored here)
|- docs/
| |- architecture.md the map: which doc owns which fact, and rules that bind app and server
| |- permissions.md who may do what, and where it is enforced
| |- releasing.md how a release is built, signed and published
| |- writing-docs.md how every doc and user-facing string is written
| `- images/ README images, drawn from the website's app mockups
|- changelog/ release notes, one file per release
|- .github/workflows/ release.yml (publish a release), build-linux.yml (test Linux builds),
| redeploy-site.yml (rebuild the website when a mirrored doc changes)
|- .claude/skills/ Claude Code skills, for example cutting a release
`- CLAUDE.md the workspace guide for AI coding agents
Clone the app, then the server and the website into it. This repository ignores both folders, so each keeps its own history. Skip either if you are not working on it.
git clone https://github.com/NotRover/RoverTools-Orange-Copy-Paste-App.git
cd RoverTools-Orange-Copy-Paste-App
git clone https://github.com/NotRover/RoverTools-Orange-Copy-Paste-Backend.git orange-copy-paste-clipboard-backend
git clone https://github.com/NotRover/RoverTools-Orange-Copy-Paste-Website.git orange-copy-paste-clipboard-websiteThe default branch is main in all three repositories. Keep each commit to one repository.
Desktop app. You need Bun, a stable Rust toolchain, and the Tauri prerequisites for your system:
cd orange-copy-paste-clipboard-app-rust
bun install
bun run tauri devThe app window opens with an empty history, and everything except sync works. To build with sync turned on, see Point the app at your server.
Sync server. You need Python 3.14 or newer, uv, Docker, and a Supabase project. The steps, from .env to a health check, are in the server README.
Run the smallest set that covers what you changed:
| You changed | Run |
|---|---|
| The app's interface | bun run build |
| The app's Rust code | cd src-tauri && cargo check |
| Clipboard capture, hotkeys, popups, paste or sync | bun run tauri dev, then try that flow by hand |
| Server Python | uv run ruff check src and uv run ty check src, plus uv run pytest for logic changes |
| Any doc or text a user reads | The checklist in docs/writing-docs.md |
Testing sync end to end needs a running server, a Supabase project and two accounts. If you could not test it, say so.
A release is one run of .github/workflows/release.yml. It publishes changelog/next.md as the release notes, bumps the version, builds signed Windows, macOS and Linux bundles, and publishes them as a GitHub Release on this repository, where the in-app updater finds them. The inputs, the stable and beta channels, and signing-key setup are in docs/releasing.md. Releases never touch the sync server, which deploys on its own.
- Commit messages: a lowercase
type(scope): subjectline, then a few single-line bullets on what changed and why. - Release notes: write
changelog/next.mdbefore releasing; an empty one stops the release. Internal changes go under### Internaland are never shown to users. - Pull requests open as drafts against each repository's own
main. - Migrations are written, never applied automatically. Writing an Alembic migration is normal work; applying it to a real database is a separate, approved step.
- Docs and user-facing text follow
docs/writing-docs.mdin all three repositories.
- orange-copy-paste-app.pages.dev: the user guide and the Developers section (architecture and security overviews, self-hosting, design records).
docs/architecture.md: the map of which doc owns which fact. Start here to find the right doc.- App README, app architecture and bug-fix history.
- Server README, server architecture and deployment guide.
- Website README: how the site is built and deployed.
CONTRIBUTING.md covers setup, checks and pull requests. Report vulnerabilities as described in SECURITY.md, never in a public issue. See also the CODE_OF_CONDUCT.md. Licensed under the GNU AGPL v3.0.
Docs are context, not truth. Where a doc and the code disagree, the code wins, and the doc is worth fixing.


