npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

mirrormux

v0.1.0

Published

Mirror a live tmux pane to your phone's browser. Watch and drive Claude Code from anywhere on your network — no app, no API key, zero runtime dependencies.

Readme

mirrormux

Mirror a live tmux pane to your phone's browser.

You are working in tmux at your desk. You walk away. You open your phone and the same screen is there — mid-task, still updating. You approve the prompt that was waiting, type the next instruction, and put your phone away.

No app to install. No API key. No account. Zero runtime dependencies.

日本語 README

⚠️ This tool types into your shell. Anyone who gets past authentication can run arbitrary commands on the host. It ships bound to 127.0.0.1 for that reason. Read SECURITY.md before exposing it to a network.


Why this exists instead of the alternatives

Most mobile coding-agent clients host the agent: a bridge server spawns a session that belongs to the app. mirrormux does the opposite — it is a remote control for a tmux pane that already exists.

That single choice is the whole product:

  • The PC and the phone see the identical screen. Not a resumed session, not a synced transcript — the same pane, because both are reading the same tmux window.
  • Your existing agent login just works. mirrormux runs nothing and authenticates to nothing. Whatever you started in tmux — Claude Code on a subscription, an SSH session, a long build — is what you see. No ANTHROPIC_API_KEY, no per-token billing.
  • Nothing to install on the phone. It is a web page (installable as a PWA if you want the fullscreen look).

If you want a polished native app with git staging, a file explorer, and Codex support, use CC Pocket — it is excellent and does far more. mirrormux is for the one thing it cannot do: showing you the pane you are already attached to.

Requirements

  • macOS or Linux with tmux installed
  • Node.js 20+
  • A phone on the same network, or a VPN / SSH tunnel back to the host

Install

npx mirrormux --init     # writes a config with a generated 24-char password
npx mirrormux            # start

--init prints the username and password once. It writes to ~/.config/mirrormux/config.json with mode 0600.

git clone https://github.com/nogataka/mirrormux.git
cd mirrormux
node server.js --init
node server.js

A config.json in the repository root takes precedence over the one in ~/.config, so cloned checkouts keep their settings local.

Connect from your phone

By default the server listens on 127.0.0.1 only — nothing outside the host can reach it. Pick one of these:

SSH port forward (safest, nothing listens on the network):

ssh -L 7690:127.0.0.1:7690 you@your-host
# then open http://127.0.0.1:7690 on the forwarding device

Mesh VPN (Tailscale / WireGuard): set "host" to your VPN interface address, then browse to http://<vpn-ip>:7690.

Trusted LAN: set "host": "0.0.0.0" and browse to http://<host-ip>:7690. The server will warn you at startup about what this exposes.

Then, on the host, run your work inside tmux:

tmux new -s main
claude          # or anything else

Panes started outside tmux are invisible to mirrormux — that is the one workflow change this tool asks of you.

What you get on the phone

  • The live pane, ANSI colors intact, following new output automatically
  • Approval prompts as buttons. Numbered agent choices are detected and normalized into Allow / Allow all / Deny, with the primary action on the right where your thumb is
  • Per-window status dots — yellow (working) / red (waiting on you) / green (idle) — so you can see which of several sessions needs you
  • A real text field, not a terminal emulator. IME works, so CJK input works. Enter inserts a newline; sending is an explicit button, so you can edit a long instruction before it goes anywhere. Voice dictation, autocorrect, and clipboard all come free from the OS
  • Width that actually fits. One tap resizes the tmux window to your phone's measured column count, so the TUI re-wraps instead of scrolling sideways. It restores itself a minute after you disconnect
  • Image attachment from the library, camera, or paste
  • A tmux admin page for creating, renaming, reordering, and killing windows, with two-step confirmation on destructive operations

Optional: notifications when you are away

Your terminal beeps when an agent finishes. Your phone, in your pocket, does not. mirrormux can post to Slack or LINE via Claude Code's Stop and Notification hooks.

The point is the idle gate: it only notifies when the host keyboard has been idle past a threshold (default 5 minutes). Sitting at your desk produces no notifications at all.

See README.ja.md for setup, or config.example.json for the shape of the notify block. This part is entirely optional — mirrormux works fine without it.

Configuration

Full reference: config.example.json. The ones that matter:

| Key | Default | Meaning | |---|---|---| | host | 127.0.0.1 | Bind address. Changing this exposes an RCE surface | | port | 7690 | | | auth.user / auth.pass | (required) | Generate with --init | | tls.cert / tls.key | (none) | Serve HTTPS; also marks the cookie Secure | | defaultTarget | null | tmux target to open first, e.g. main:0 | | shortcuts | a couple | One-tap text buttons above the input | | launchPresets | [] | Directories the admin page may start sessions in. Phones cannot send arbitrary paths — only these | | allowedHosts | [] | Extra hostnames accepted in the Host header |

CLI

mirrormux                start
mirrormux --init         create a config with a generated password
mirrormux --revoke       log out every device
mirrormux --config PATH  use a specific config file
mirrormux --help

Lost your phone? mirrormux --revoke invalidates every session token immediately.

Running it as a service

bash scripts/install-launchd.sh    # macOS, via launchd

Logs land in ~/Library/Logs/mirrormux/. On Linux, write a systemd user unit pointing at node /path/to/server.js.

How it works

tmux pane (the source of truth)
   ↑                    ↑
your terminal      mirrormux server
  (attached)      capture-pane / send-keys
                          ↓ SSE
                   phone browser

Reading is tmux capture-pane -p -e on a poll, diffed and pushed over SSE. Writing is tmux send-keys -l, which delivers the whole string literally in one burst — no per-keystroke race with the TUI redrawing, and no escape-sequence interpretation.

mirrormux never attaches, so it never fights your terminal over the window size.

Limitations

  • tmux is required, and your work has to run inside it
  • Agent approval detection reads on-screen text, so an agent's UI redesign can break it. The design is fail-soft: detection failing costs you the buttons, not the ability to type
  • Slash-command autocomplete does not appear — type the full command, or put it in shortcuts
  • macOS/Linux only; the notification idle gate uses macOS ioreg today

License

MIT — see LICENSE.

Not affiliated with Anthropic, OpenAI, or the tmux project.