Klip

Native clipboard access for Go on Linux (Wayland and X11), macOS and Windows. No cgo.

Built to solve the “copied a password, program exited, clipboard went blank” problem you get on Wayland with most clipboard libraries. On Linux, Klip shells out to wl-copy, xclip or xsel, which fork and keep serving the clipboard after your process exits. On macOS it uses pbcopy and osascript; on Windows it talks to the Win32 clipboard API directly. Kosh uses it to copy secrets.

Source

Install

go get plutolab.org/klip

Usage

cb := klip.NewClipboard()

// plain copy
cb.Write(ctx, []byte("hello"), klip.WriteOptions{})

// copy a secret: hint clipboard managers to keep it out of history,
// and clear it after the first paste where supported
cb.Write(ctx, []byte(password), klip.WriteOptions{
	Secret:       true,
	ClearOnPaste: true,
})

// clear now, but only if the clipboard still holds what we wrote
cb.Clear(klip.DirectCompare([]byte(password)))

// clear unconditionally
cb.Clear(klip.Always)

Platform support

Clear-on-paste only exists where the OS lets a process serve its own clipboard selection on request (Wayland, X11). macOS and Windows hand clipboard content to the OS immediately, with no way to observe a paste, so there's nothing to hook there.

Clearing on a timeout

Klip has no background timer of its own. A library can't safely spawn one that outlives your process without doing something surprising to every program that imports it. Instead:

Your app registers its own worker entry point (a hidden subcommand, same idea as gopass unclip), calls LaunchDetached right after Write, and has that worker call ClearAfter.

Known gaps

On Linux, KDE's Klipper re-asserts old content after a plain clear. A fix exists but isn't wired in yet: it works by wiping Klipper's entire history, not just the one entry, which isn't always the right tradeoff.

Releases