Sparsh

Install

Put the CLI on a machine, pair two devices, and send the first file.

The browser needs nothing

Open the app on both devices. One shows a code or a link, the other opens it. That is the whole install, and it is the point: the far end never has to install anything.

The CLI

git clone https://github.com/jvoltci/sparsh && cd sparsh/frontend && npm install

There is no published release yet. sparsh-cli on npm is the reserved name and nothing more: its own description says "not yet functional". The bare name sparsh was refused outright, because it sits two edits from slash, which is pulled 123 million times a week, and that guard is not appealable.

So every sparsh <command> on this site is npm run peer -- <command> from frontend/ today. The forms and the flags are identical; only the prefix differs.

Check it:

npm run peer -- whoami

That prints this device's public key as an npub, its name, and the devices it has paired with. The key is generated once and kept in ~/.sparsh/state.json, mode 0600. A stolen state file is this device, so it is treated that way.

Pair two devices, once

On the device that will be reached:

sparsh invite

It prints a link and waits. Open the link on the other device, or hand the token to sparsh pair there. The two now know each other's keys, and neither needs a code again, on any network.

sparsh devices

A human does this step, always. An agent is never given a verb for pairing, and the daemon refuses a session from a key it has not been introduced to. That line is what separates a useful network from a prompt-injection amplifier.

Send something

sparsh send report.pdf --to "Phone"

No code. The pairing is the authorisation, and the name is enough.

Stay reachable

A cold send pays about 0.59 s before the first byte: signalling, ICE, DTLS. A second send on the same session pays about 0.7 ms. So a resident process is worth more than any change to the wire:

sparsh serve --into ~/Downloads

That keeps sessions warm and keeps this device findable, so a paired device can send to it unprompted. It exits on its own after ten idle minutes, because a background process nobody asked for is a bug however small.

Environment

SPARSH_HOME moves the identity and the pairings. SPARSH_SIGNALING_URL points at a signalling server; without one, the public Nostr relays are used and there is no device discovery. The full list is on the CLI page.

The older TELEPORT_* names are still read. Sparsh was called Teleport until 2026-09-19, and dropping them would break every shell profile already written, silently, because an unset variable just falls back to a default.

On this page