Thanks to visit codestin.com
Credit goes to lib.rs

#screenshot #clipboard #cross-platform

app shotpaste

One screenshot, three pastes. Atomic multi-format clipboard (image + file + path) on Windows, macOS, and Linux.

6 releases

Uses new Rust 2024

0.3.0 May 12, 2026
0.2.0 May 12, 2026
0.1.6 May 10, 2026

#597 in Filesystem

MIT license

110KB
2K SLoC

shotpaste

One screenshot, three pastes.

shotpaste demo: one screenshot, three pastes

CI Crates.io Downloads Release License: MIT platform

shotpaste is a tiny background daemon that watches your screenshot folder. When a new screenshot lands, it copies it to the clipboard as image bytes, a file-drop list, and the file path as text — all at once, in a single clipboard write. Then one paste does the right thing in any app:

   Press PrtScn  →  shotpaste sees the new PNG  →  writes the clipboard once with:

      ├──── image bytes ────►  Slack, WhatsApp, Discord, image editors, browsers
      ├──── file-drop list ─►  JIRA upload, file pickers, file managers
      └──── text path ──────►  terminals, editors, markdown previews

No more screenshotting twice. No more drag-from-Explorer. No more "wait, which paste does this app want?"


Install

# macOS / Linux
curl -fsSL https://github.com/ebrahim-sameh/shotpaste/releases/latest/download/shotpaste-installer.sh | sh
shotpaste install
# Windows
irm https://github.com/ebrahim-sameh/shotpaste/releases/latest/download/shotpaste-installer.ps1 | iex
shotpaste install

The first line drops a single static shotpaste binary on disk (~/.cargo/bin on Linux/macOS, %CARGO_HOME%\bin or ~\.cargo\bin on Windows). The second registers it to start at login.

Want to inspect the install script first? curl -fsSL <url-from-above> prints it. The releases page also publishes the sha256 of every artifact.

Already have a Rust toolchain? You can also install from crates.io (builds from source — slower than the prebuilt installer above):

cargo install shotpaste
shotpaste install

Quickstart

  1. Press your normal screenshot shortcut (Win+PrtScn, Cmd+Shift+3, PrtScn).
  2. Paste anywhere with Ctrl+V / Cmd+V.
  3. That's it.

Verify with shotpaste status. The default watched folder is your OS's standard screenshot directory; pass a different path to shotpaste watch to override.

Why not just use ShareX / Greenshot / Snipping Tool?

Existing screenshot tools either give you the image on the clipboard or the file path, never both — and almost none of them are cross-platform. shotpaste is a single static binary that does all three formats simultaneously on Windows, macOS, and Linux.

Tool Image paste File-drop paste Path-text paste All three in one paste AI coding tools Cross-platform FOSS Price
shotpaste Win + macOS + Linux ✓ MIT Free
ShareX Windows only ✓ MIT Free
Greenshot / Flameshot varies Free
Lightshot Win + macOS Free
CopyCut / winclipshot Windows only Free
Snagit Win + macOS Paid
Snipping Tool / macOS Screenshot native bundled Free

ShareX has separate "Copy image" and "Copy file path" after-capture actions, but doing both formats from a single capture has been a long-standing open feature request. shotpaste does it by default.

Coming from Higangssh/winclipshot? shotpaste does the same path-on-clipboard trick — but puts it alongside the image and file-drop formats instead of replacing them. You keep the path-paste superpower in your terminal without losing image-paste in Slack/WhatsApp/Discord. And it works on macOS and Linux, not just Windows.

Use cases

Bug report to your team. A 500 error appears. You screenshot the stack-trace overlay. In your team's Slack thread: Cmd+V → image attached, everyone sees it. Click into the JIRA ticket's "Drop files here" zone, Cmd+V again → same screenshot uploads as a real .png file attachment, not a paste-as-image. Two pastes, zero file-manager round-trips.

UI bug from QA → GitHub PR. QA screenshots a misaligned modal. Slack: Cmd+V → image inline for the squad. GitHub PR description: Cmd+V → path pasted, ready to wrap as ![](...). Same clipboard, both contexts.

Notion + a markdown changelog. You're writing release notes in Notion and a CHANGELOG.md at the same time. Same screenshot. Notion: Cmd+V renders inline. VS Code on the markdown file: Cmd+V pastes the absolute path. The image is right there in both surfaces, no alt-tabbing.

WhatsApp Web + a remote terminal. Screenshot a failing CI log. WhatsApp Web in the browser: Ctrl+V → image attached to the team chat. SSH session in the next tab: vim "$(Get-Clipboard)" (PowerShell) or vim "$(xclip -o)" (Linux) opens the very same screenshot — because the path text is also on the clipboard.

Screenshot → Claude Code / Cursor. A weird CSS bug appears in your browser. Screenshot it. In Claude Code or Cursor's chat panel: Cmd+V → image attaches and the agent sees the bug. Need it to read the source file too? Same paste in the agent's terminal or a @file reference — the absolute path is on the clipboard, so the agent can Read the file and grep nearby code. One screenshot, both halves of the loop.

How it works

  1. A small background daemon watches your screenshot folder using each OS's native filesystem-event API (ReadDirectoryChangesW on Windows, FSEvents on macOS, inotify on Linux).
  2. When a new .png lands, the daemon decodes it and builds a single multi-format clipboard write.
  3. The OS's native multi-format clipboard API gets all three formats in one transaction — IDataObject on Windows, NSPasteboard.writeObjects: on macOS, atomic wl_data_source (Wayland) or X11 selection ownership (X11) on Linux.

About 1 MB of compiled Rust per platform, statically linked, zero runtime dependencies you have to install yourself.

Configuration

Default watched folder per platform (used when neither CLI args nor config specifies):

  • Windows: %USERPROFILE%\Pictures\Screenshots (Win+PrtScn default)
  • macOS: ~/Desktop (Cmd+Shift+3 / 4 / 5 default — to relocate, run defaults write com.apple.screencapture location ~/Pictures/Screenshots && killall SystemUIServer)
  • Linux: ${XDG_PICTURES_DIR:-$HOME/Pictures}/Screenshots (the GNOME / KDE Spectacle default)

Watch multiple folders

Pass several paths on the CLI:

shotpaste watch ~/Pictures/Screenshots ~/Desktop/Scratch ~/Downloads/Captures

Or set watch_dirs in <config_dir>/shotpaste/config.toml (read by the auto-started daemon):

notify_on_success = true
notify_on_error = true
watch_dirs = [
    "C:/Users/you/Pictures/Screenshots",
    "C:/Users/you/OneDrive/Pictures/Screenshots",
    "C:/Users/you/Desktop/Scratch",
]

Precedence: CLI args > watch_dirs in config.toml > OS default. One process handles all folders — no per-folder daemon. From the tray icon you can also click "Add watched folder…" to pick a folder graphically, or Remove from watch list on any entry to drop it.

Logs:

  • Windows: %LOCALAPPDATA%\shotpaste\shotpaste.log.<date> (daily-rolling, written whenever the tray is active), otherwise stderr if run from a console.
  • macOS: ~/Library/Logs/shotpaste.log
  • Linux: journalctl --user -u shotpaste

Set SHOTPASTE_LOG=debug in the environment for verbose tracing.

Tray UI

shotpaste tray menu — right-click shows watching dir, last capture time, session push counter, open/replay/log actions, autostart + notify toggles, quit

When run interactively (shotpaste watch from a desktop session, or auto-started by the installer), shotpaste shows a small system-tray icon with a right-click menu: open watched folders, add or remove folders via a native picker, replay the last screenshot, toggle "Start at login", and toggle success/error toast notifications. A toast pops up on each successful push (bursts coalesce inside a ~1.5s window). Errors always toast.

When watching two or more folders the menu collapses into a Watched folders ▶ submenu — each entry expands to "Open in file manager" and "Remove from watch list". The "Add watched folder…" item is always present.

Skip the tray with shotpaste watch --headless — useful in SSH sessions, servers, or when running under another supervisor. Linux without a display ($DISPLAY and $WAYLAND_DISPLAY both unset) auto-detects and falls back to headless.

To build a slim binary without any GUI deps, use cargo install shotpaste --no-default-features — drops tao / tray-icon / notify-rust (~3 MB off the binary).

GNOME users: GNOME doesn't show legacy tray icons natively. Install gnome-shell-extension-appindicator (it's pre-packaged on Ubuntu) to see shotpaste's tray icon. The watcher and toast notifications work either way.

macOS — file-drop is disabled by default. Mac Catalyst apps (WhatsApp, Messages, News, Voice Memos, …) bridge NSPasteboard to iOS-style UIPasteboard handlers that don't expect Mac file:// paths and crash with SIGABRT when they see a file URL on the clipboard. shotpaste therefore writes only the image and path-text formats on macOS by default — Cmd+V still works correctly in chat apps, browsers, image editors, and code editors. To re-enable the file-drop format (e.g. so Cmd+V in Finder pastes the screenshot as a file), set SHOTPASTE_INCLUDE_FILES=1 in the LaunchAgent's environment:

# Edit ~/Library/LaunchAgents/dev.shotpaste.watcher.plist and add inside <dict>:
#   <key>EnvironmentVariables</key>
#   <dict>
#     <key>SHOTPASTE_INCLUDE_FILES</key>
#     <string>1</string>
#   </dict>
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/dev.shotpaste.watcher.plist
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/dev.shotpaste.watcher.plist

Windows and Linux are unaffected and write all three formats unconditionally.

Privacy

shotpaste is a local-only tool. No network calls, no telemetry, no uploads. The only network connection is when you run the install script — to download the release archive from GitHub Releases.

Uninstall

# macOS / Linux
shotpaste uninstall          # removes autostart entry
shotpaste uninstall --purge  # also removes config dir
rm ~/.cargo/bin/shotpaste    # removes the binary
# Windows
shotpaste uninstall          # removes Scheduled Task
shotpaste uninstall --purge  # also removes config dir
Remove-Item ~\.cargo\bin\shotpaste.exe

Roadmap

Considering for future releases (no commitments):

  • Per-format toggles (disable file-drop on systems where it conflicts)
  • Optional auto-upload format (imgur / 0x0.st URL alongside image+file+path, opt-in only)
  • Filename templates ({app}_{yyyy-MM-dd}_{HHmmss}.png)
  • OCR text format — paste OCR'd text into editors instead of the path
  • Windows ARM64 build (currently deferred — cargo-dist 0.31 cross-compile container has an apt-get prompt issue)

Contributing

Issues and PRs welcome. The code is small (~700 lines of Rust). Before opening a PR:

cargo build
cargo test
cargo clippy --all-targets -- -D warnings
cargo fmt --all -- --check

CI runs the same on Ubuntu, Windows, and macOS.

License

MIT — see LICENSE.

Acknowledgements

Dependencies

~20–67MB
~1M SLoC