Think ngrok, but for keystrokes

Let your colleague
type into your terminal.

You're screensharing. They need to run a command. Stop dictating characters. Give them a session code and let them type directly.

Terminal — host
$
keytun v0.1.0
Session: keen-fox-42
Waiting for client...
✓ Client connected
$
Terminal — helper
$
Connected to keen-fox-42
You are now typing into the remote terminal.
Press Esc twice to disconnect.

The problem with screensharing

Dictating commands

"Capital D, dash, dash, no-cache, space, dot, no the other dot..."

Swapping screen control

Request control, wait for approval, fumble with resolution differences, give it back.

Full pair-programming tools

VS Code Live Share, tmate, tmux — all overkill for "let me just type this one command."

keytun

Share a code. They type. You see it live on your screenshare. Done.

How it works

Host

Developer screensharing.
Runs keytun host

WebSocket
Relay

Stateless broker.
Bridges connections.

WebSocket
Client

Helper colleague.
Runs keytun join <code>

1

Host starts a session

Run keytun host. A PTY spawns your shell. You get a session code like keen-fox-42.

2

Share the link over your call

You get a direct join link like keytun.com/s/keen-fox-42. Drop it in chat — your colleague opens it in their browser. No install needed.

3

Helper joins and types

They can join from the browser or via CLI. Raw key bytes flow through the relay to the host's PTY. Arrow keys, tab completion, Ctrl+C — everything works.

4

Host sees it live

Both local and remote input appear in the same terminal. Your screenshare shows everything in real time.

See it in action

Three ways to use keytun — pick what fits your workflow.

1

Host starts a session

Run keytun host to spawn a PTY and get a session code.

Host terminal
$ keytun host
keytun v0.1.0
Session: keen-fox-42
Waiting for client...
2

Colleague joins via CLI

Your colleague runs keytun join with the session code.

Client terminal
$ keytun join keen-fox-42
Connected to keen-fox-42
You are now typing into the remote terminal.
Press Esc twice to disconnect.
3

Keystrokes flow in real time

The client types commands — they appear in the host's PTY. Arrow keys, tab completion, Ctrl sequences all work.

Client types
docker compose up -d
Host sees
✓ Client connected
$ docker compose up -d
Arrow keys Tab completion Ctrl+C Full PTY
1

Host starts in system mode

Target a specific application window by name. Keystrokes are injected at the OS level.

Host terminal
$ keytun host --mode system --target "VS Code"
keytun v0.1.0
Mode: system → targeting "VS Code"
Session: bold-owl-17
Waiting for client...
2

Colleague joins and types

Same join flow — but keystrokes go to the targeted app, not a terminal.

Client terminal
$ keytun join bold-owl-17
Connected to bold-owl-17
Target: VS Code (system mode)
Press Esc twice to disconnect.
3

Keystrokes appear in the app

Your colleague types code into your IDE while you watch on screenshare. Works with any app that accepts keyboard input.

VS Code — main.go
14func handleRequest(w http.ResponseWriter, r *http.Request) {
15 if r.Method != "POST" {
16 http.Error(w, "method not allowed", 405)
17 }
Any application Window targeting OS-level injection macOS only
1

Host shares a link

The host gets a direct join URL — just drop it in the call chat.

Host terminal
$ keytun host
keytun v0.1.0
Session: keen-fox-42
Join: keytun.com/s/keen-fox-42
Waiting for client...
2

Colleague opens the link in their browser

No install needed. The browser connects via WebSocket with end-to-end encryption.

keytun.com/s/keen-fox-42
Connected
$ _
End-to-end encrypted · Session keen-fox-42
3

Full terminal in the browser

A real terminal emulator powered by ghostty-web. Your colleague sees output and types commands — just like a local shell.

keytun.com/s/keen-fox-42
Connected to keen-fox-42
$ ls -la
drwxr-xr-x 12 user staff 384 Mar 27 10:04 .
-rw-r--r-- 1 user staff 1247 Mar 27 10:04 main.go
-rw-r--r-- 1 user staff 893 Mar 27 09:58 go.mod
$ go test ./...
No install E2E encrypted Full terminal Esc×2 to disconnect

Built for developers

Single binary

Go binary. No runtime, no dependencies. Download and run.

Readable session codes

Wordlist-based codes like keen-fox-42. Easy to say over a call.

End-to-end encrypted

E2EE

X25519 key exchange + AES-256-GCM. The relay is a dumb pipe — it never sees your keystrokes or output.

Self-hostable relay

Stateless WebSocket broker. Deploy on Fly.io, Railway, or any container host.

Browser client

Your colleague doesn't need to install anything. Share a link and they join straight from the browser.

Lightweight

No database, no auth tokens, no persistence. Sessions live in memory.

Get started

Shell

Recommended
Terminal
$ curl -fsSL keytun.com/install.sh | sh

Homebrew

macOS
Terminal
$ brew install --cask gboston/tap/keytun

Roadmap

What's coming next.

Up next
security

Connection approval

Host approves each client before keystrokes start flowing. Full control over who gets access.

security

Password-protected sessions

Host sets a password when starting a session. Clients must enter it before keystrokes flow.

Planned
  1. Read-only mode Join as a viewer — see terminal output without being able to type.
    feature
  2. Linux system mode OS-level keystroke injection via xdotool/ydotool, matching macOS system mode.
    platform
  3. Latency indicator Round-trip time in the client status bar so you know whether lag is keytun or your connection.
    ux
  4. Connection notifications Audible and visual notifications when a client joins or leaves your session.
    ux