The command-line client
For the machines that have no clipboard at all. It reads standard input and writes standard output, so it composes with everything else you already use — and it is not a second implementation, it imports the very same encryption and transport files the browser runs.
Not on npm yet. npx realtimeclipboard is what it
will be; until the first release is published, run the same client from
a clone — node cli/realtimeclipboard.mjs D75LV. Every
command below works either way.
Install it
npx realtimeclipboard D75LV
There is nothing to install: npx fetches it, runs it and
leaves nothing behind. If you would rather have it on your path:
npm install -g realtimeclipboard
Node 22 or newer is required, for the built-in
WebSocket. On an older Node the client exits immediately
and says so rather than failing halfway through a transfer.
Or from a package manager
brew install akshaynikhare/tap/realtimeclipboard-cli
Note the name: the CLI formula is realtimeclipboard-cli
and the desktop app is the realtimeclipboard cask. They
are different things and installing one does not give you the other —
a server wants the pipe, not a menu-bar icon.
Check it worked
npx realtimeclipboard --version
Connecting prints one status line to standard error, never standard output:
realtimeclipboard · room 3f2a91c4…
That is the room hash, truncated — never the key. Because it goes to
stderr, watch > file still writes only the clip. Pass
-q to silence it entirely.
Your first sync
- Open the app in a browser and note the key.
- On the server, send something to it:
echo "deploy key" | npx realtimeclipboard send D75LV - It appears in the browser. Now go the other way — copy something in
the browser, and on the server run:
npx realtimeclipboard watch D75LV --once > token.txt
The four commands
| Command | What it does |
|---|---|
realtimeclipboard <KEY> | Two-way: prints what arrives, sends what you type |
realtimeclipboard watch <KEY> | Print incoming clips |
realtimeclipboard send <KEY> | Read stdin to EOF and send it |
realtimeclipboard new [--long] | Print a fresh key |
Options: --relay <url>, --pin <pin>,
--once, --json, --timeout <s>,
-q, -h, -v. The relay and the PIN
also read from REALTIMECLIPBOARD_RELAY and
REALTIMECLIPBOARD_PIN, which is the right way to pass a
PIN — an argument lands in your shell history.
# structured output, one JSON object per line
npx realtimeclipboard watch D75LV --once --json | jq -r .text
# from a box you are ssh'd into
ssh build-01 'cat /var/log/deploy.log' | npx realtimeclipboard send D75LV
# against your own relay
npx realtimeclipboard --relay wss://clip.example.com D75LV
When it does not work
“this needs Node 22 or newer”
Exactly what it says: the client uses Node's built-in
WebSocket rather than pulling a dependency in, and that
landed in 22. It exits at startup rather than mid-transfer.
It hangs and never prints anything
watch waits for a clip by design — nothing arrives until
something is copied at the other end. Use --timeout 30 in
a script so it cannot wait forever, and --once so it exits
after the first clip.
It works interactively but not in CI
There is no TTY, so pass -q and read standard output. Put
the key in an environment variable rather than the command line, where
it would show up in build logs.
Nothing connects from behind a proxy
The client speaks the same protocol as the browser and can be pointed
at your own relay with --relay.
Running one is one container.
Uninstalling
npx leaves nothing to uninstall.
npm uninstall -g realtimeclipboard if you installed it
globally, or brew uninstall realtimeclipboard-cli.
The key is a bearer credential. Anyone holding it can read the session while it is open, so keep it out of shell history, out of CI logs and out of committed files. Clip contents are encrypted on this machine before they are sent; the relay only ever sees a room hash and ciphertext.
Every other platform: the installation guide. Something wrong or out of date here? Open an issue.