← Clipnest

Contribute

The details behind the one-line install, plus how to build Clipnest and help improve it. If you just want to use Clipnest, the Download page is all you need.

Manual install

Prefer not to pipe a script into a shell? Download the release yourself from GitHub Releases and verify it first.

macOS

Download Clipnest-<version>.dmg and its Clipnest-<version>.dmg.sha256 into the same folder, then check the checksum before you open anything:

Terminal · macOS
shasum -a 256 -c Clipnest-*.dmg.sha256

It should print OK. Open the .dmg and drag Clipnest into Applications. A browser download is quarantined by macOS, so the first launch shows an “unidentified developer” warning. On macOS 15 (Sequoia) and later that dialog has no Open button: dismiss it, open System Settings → Privacy & Security, scroll to the message about Clipnest, click Open Anyway and confirm (macOS asks for your admin password). On macOS 14, Control-click Clipnest in Applications and choose Open also works. Or, from Terminal on any version, clear the flag once:

Terminal · macOS
xattr -dr com.apple.quarantine /Applications/Clipnest.app

Linux

Download clipnest-<version>-linux-amd64.tar.gz (or -arm64; run uname -m if unsure: x86_64 is amd64, aarch64 is arm64), then:

Terminal · Linux
tar xzf clipnest-*-linux-amd64.tar.gz
cd clipnest-*-linux-amd64
sha256sum -c SHA256SUMS
./install.sh          # as your normal user, not with sudo

The bundled install.sh checks the architecture and installs three packages with apt: clipnest, plus clipnest-ocr and clipnest-ocr-data for text recognition in images. To skip OCR (about 26 MB), install only the app: sudo apt-get install --no-install-recommends ./clipnest_*.deb. On GNOME, apt also prints a one-line notice at install time: the Clipnest Shell extension is set up automatically the first time you open Clipnest, and you log out and back in once to activate the hotkey.

Installer options

Set these in front of bash to change how the one-line installer behaves, for example:

Terminal
curl -fsSL https://raw.githubusercontent.com/AayushGour/clipnest/main/scripts/install.sh | CLIPNEST_DRY_RUN=1 bash
Option Applies to What it does
CLIPNEST_DRY_RUN=1 install.sh, uninstall.sh Do everything except the actual change: detect, download and verify for install; print each action for uninstall.
CLIPNEST_FORCE=1 install.sh, Linux Continue on a system that isn’t Ubuntu 22.04/24.04 with GNOME. Unsupported; it may not work.
GITHUB_TOKEN install.sh, update.sh A GitHub personal access token (no scopes needed for a public repo). Only raises the GitHub API rate limit from 60 to 5000 requests an hour per IP. Never printed or written to disk.
CLIPNEST_VERSION=vX.Y.Z update.sh, macOS Install exactly that release instead of the latest. Must match vN.N.N or the script exits. The in-app updater sets this and fetches the script from the same tag.
CLIPNEST_RELEASE_IDENTITY install.sh, update.sh, macOS Signing-identity name expected on the new app when there is no installed app to compare against (default Clipnest Release).
REQUIRE_CHECKSUM=false install.sh, update.sh, macOS By default the install stops if a release has no published checksum. false allows an unverified .dmg from an old release that predates checksums. Not recommended. A checksum mismatch always stops the install.
--purge or CLIPNEST_PURGE=1 uninstall.sh Also delete your history, snippets and settings. Pass it as bash -s -- --purge. On Linux it also removes the clipnest-input group, so log out and back in afterwards.

The installer needs curl, plus tar, sha256sum (or shasum), sudo and apt-get on Linux. On Linux it checks the tarball against the SHA-256 GitHub publishes for that release file (it stops if that is missing or different), then checks the files inside with the bundled SHA256SUMS.

Updating

On a Mac, run the update script. It installs the latest version if a newer one exists, with the same checksum verification as the installer. Before replacing anything it checks that the new app’s version matches the release and that its code signature is valid and made by the same signer as your installed copy (a mismatch aborts with a SECURITY message and leaves your app untouched). The new app is copied next to the old one and swapped in only after those checks pass, and the old one is restored if the swap fails.

Terminal · macOS
curl -fsSL https://raw.githubusercontent.com/AayushGour/clipnest/main/scripts/update.sh | bash

You can also click the version number in the picker footer (it shows a small dot when an update is available) and confirm: Clipnest opens Terminal, runs the update script from the release tag being installed (not main), then relaunches itself.

On Linux, run the install command again (it installs the latest release over the current one), or download the newer tarball and run its install.sh. Or use Settings → General → Check for Updates Now: for a tarball install, Clipnest can download, checksum-verify and install the update after you confirm with Install Update…. It never installs anything on its own.

Uninstalling by hand

Mac: drag Clipnest from Applications to the Trash. To also remove its local data:

Terminal · macOS
rm -rf ~/Library/Application\ Support/Clipnest \
       ~/Library/Preferences/com.clipnest.app.plist \
       ~/Library/Caches/com.clipnest.app \
       ~/Library/HTTPStorages/com.clipnest.app

Linux:

Terminal · Linux
sudo apt remove clipnest clipnest-ocr clipnest-ocr-data

Your Linux history in ~/.local/share/Clipnest is left in place; delete that folder too to remove everything.

Signing, honestly (Mac)

Clipnest is not distributed through the Mac App Store or a notarized, Developer-ID-signed .dmg by default. The supported install path (scripts/install.sh / scripts/update.sh) downloads with curl, which never sets the com.apple.quarantine flag — that flag, not the code signature, is what triggers Gatekeeper’s “unidentified developer” check and its notarization gate, so a browser-downloaded copy would need it and a curl-installed one doesn’t. In place of Gatekeeper, those scripts verify the .dmg against a SHA-256 checksum published alongside every release, and refuse to install anything unverifiable.

Every release is still signed — with one long-lived, self-signed certificate (scripts/release-cert.sh, run once ever), not a throwaway ad-hoc identity. That matters because macOS ties an Accessibility grant to the app’s designated code requirement: an ad-hoc build gets a new one every build and would invalidate every user’s grant on each update, while signing every release with the same certificate keeps the requirement — and the grant — stable across updates. This is not a Developer ID and does not enable notarization on its own; if the maintainer sets real Apple Developer ID + notary secrets in the repo, the release workflow signs and notarizes with those instead for a fully Gatekeeper-clean .dmg. Without them, releases ship a self-signed (not notarized) .dmg, verified the way described above.

None of this requires an Apple Developer account to build, run, or even distribute Clipnest via the supported curl-based install path — an account is only needed for the optional Gatekeeper-clean, notarized .dmg instead.

Linux details

Clipnest runs on Ubuntu 22.04 and 24.04 with GNOME, on X11 or Wayland, for amd64 and arm64.

Logs: journalctl --user -t app.clipnest.Clipnest follows the app’s log.

Build from source

Clone the repo and build it yourself. The full steps, with every flag, are in the README: build on the Mac (Xcode 16+ and XcodeGen) and build on Linux (inside the official Swift Docker image). The short version:

Terminal
git clone https://github.com/AayushGour/clipnest.git
cd clipnest
make test      # unit tests: swift test on a Mac, Docker on Linux
make build     # app build; run `make` to list every target

The core logic is a plain Swift package with no Xcode dependency, so most changes can be developed and tested from the command line. Run make on its own to see every target, including make deb, make dmg and make lint.

Report a bug or send a PR

Issues, ideas and pull requests are welcome.

Back to the Download page, the usage guide, or the source on GitHub.