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

shell-cluster

v1.0.14

Published

Decentralized remote shell access via tunnels — Node.js server with node-pty and xterm-headless

Readme

Shell Cluster

Decentralized remote shell access across all your machines. No central server required.

Cross-platform (macOS / Windows / Linux) -- each machine runs a lightweight daemon that peers discover automatically via shared tunnel credentials. Connect to any machine's shell from anywhere, like SSH but without managing keys or servers.

中文文档

How It Works

macOS (zsh)                Windows (PowerShell)         Linux (bash)
┌──────────────┐          ┌──────────────┐          ┌──────────────┐
│    daemon    │          │    daemon    │          │    daemon    │
└──────┬───────┘          └──────┬───────┘          └──────┬───────┘
       │                         │                         │
  ═════╪═════════ Tunnel (P2P, no server) ═════════════════╪═════
       │                         │                         │
  CLI / Web Dashboard (from any machine, any OS)

No central server. Every node is equal. Nodes discover each other by querying the tunnel provider's API for tunnels tagged with a shared label -- all under the same account. No relay, no coordinator, no single point of failure.

Platform Support

| Platform | Server (daemon) | Client (dashboard) | Shell | |----------|:-:|:-:|---| | macOS | Yes | Yes | zsh, bash, fish, ... | | Windows | Yes | Yes | pwsh (PS 7+), PowerShell, cmd, Git Bash, ... | | Linux | Yes | Yes | bash, zsh, fish, ... |

Install

Requires Node.js 18+.

Install globally

npm install -g shell-cluster

Try without installing (macOS/Linux only)

npx shell-cluster start --no-tunnel --port 9876

Note: npx does not work on Windows due to node-pty native addon file locking. Use npm install -g instead.

Install as a background service (recommended)

Use easy-service to run shell-cluster as a persistent background service that auto-starts on login. No admin/sudo required.

easy-service install shellcluster -- shellcluster start

This creates a native user-level service (LaunchAgent on macOS, systemd --user on Linux, Task Scheduler on Windows).

Install from local source

git clone [email protected]:billxc/shell-cluster.git
cd shell-cluster
npm install
npm link  # makes `shellcluster` available globally

Quick Start

Option A: Using Dev Tunnel (default)

1. Install

npm install -g shell-cluster

2. Login to Dev Tunnel (once per machine)

devtunnel user login

Use the same Microsoft account on all machines.

3. Start (each machine)

shellcluster start

On first run, if no config exists, a default config is created with hostname as node name. The daemon checks that devtunnel is installed and logged in before starting.

4. Open Dashboard (any machine)

shellcluster dashboard

Opens your browser — left sidebar shows all discovered peers, right side is a full xterm.js terminal. Click a peer to open a shell, manage multiple sessions in tabs. Use the Discover button to trigger an immediate peer refresh.

Option B: Using Tailscale

Tailscale runs in userspace-networking mode — no sudo, no TUN device, no impact on your normal network.

1. Install

npm install -g shell-cluster
brew install tailscale  # or see https://tailscale.com/download

2. Start Tailscale (once per machine)

# Start the daemon (no sudo needed)
tailscaled --tun=userspace-networking

# Login (in another terminal)
tailscale login

Use the same Tailscale account on all machines.

3. Configure shell-cluster to use Tailscale

shellcluster config tunnel.backend tailscale
shellcluster config tunnel.port 9876

All machines in the same cluster should use the same port. If the port conflicts on a specific machine, encode a custom port in the Tailscale hostname:

tailscale set --hostname=my-mac-p9877  # this machine uses port 9877

4. Start (each machine)

shellcluster start

5. Open Dashboard (any machine)

shellcluster dashboard

Run as a background service (recommended)

easy-service install shellcluster -- shellcluster start

The daemon runs in the background and auto-starts on login.

Architecture

  • node-pty for cross-platform PTY management
  • xterm-headless on server for full terminal state tracking per session
  • SerializeAddon for perfect state replay on reconnect (replaces raw scrollback buffer)
  • WebSocket /raw endpoint: binary frames for PTY data, JSON text frames for control
  • HTTP /sessions endpoint: list active sessions
  • Dashboard API (port 9000): /api/peers, /api/version, /api/refresh-peers, WebSocket proxy

Why Decentralized?

| | Shell Cluster | Traditional (SSH + bastion) | |---|---|---| | Central server | None | Bastion host required | | Key management | None (tunnel auth) | SSH keys on every machine | | NAT traversal | Built-in via tunnel | Port forwarding / VPN | | Discovery | Automatic | Manual inventory | | Single point of failure | None | Bastion goes down = no access | | Cross-platform | macOS + Windows + Linux | SSH server setup varies per OS |

Command Reference

| Command | Description | |---------|-------------| | shellcluster start | Start daemon (tunnel + shell server + discovery + dashboard API) | | shellcluster start --no-tunnel --port 9876 | Start in local mode (no tunnel) | | shellcluster start --dashboard-port 19000 | Use custom dashboard API port | | shellcluster register | Register this machine to the cluster | | shellcluster unregister | Remove this machine from the cluster | | shellcluster peers | List discovered peers | | shellcluster config | Show config path and all values | | shellcluster config <key> [value] | Get or set a config value (e.g. node.name) | | shellcluster dashboard | Open web dashboard | | -v / --verbose | Enable debug logging |

Configuration

| OS | Config path | |---|---| | macOS | ~/Library/Application Support/shell-cluster/config.toml | | Linux | ~/.config/shell-cluster/config.toml | | Windows | %LOCALAPPDATA%\shell-cluster\config.toml |

[node]
name = "my-macbook"        # Node name, shown in peers and dashboard
label = "shellcluster"     # Tunnel label — same label = same cluster
dashboard_port = 9000      # API + WebSocket proxy port

[tunnel]
backend = "devtunnel"      # Tunnel backend: "devtunnel" or "tailscale"
expiration = "30d"          # Tunnel auto-expiration (devtunnel only)
port = 0                   # Fixed port for shell server (0 = random, set for tailscale)

[shell]
command = ""               # Default shell (empty = auto-detect)

Development

See archived/DESIGN.md for architecture details.

git clone [email protected]:billxc/shell-cluster.git
cd shell-cluster
npm install
node src/cli.js start --no-tunnel --port 9876

Running Tests

npm test            # all tests
npm run test:unit   # unit tests only
npm run test:e2e    # end-to-end tests only

Service Management

Manage the background service installed via easy-service:

easy-service status shellcluster    # Check if running
easy-service stop shellcluster      # Stop
easy-service start shellcluster     # Start again
easy-service restart shellcluster   # Restart
easy-service uninstall shellcluster # Remove the service

Roadmap

  • [x] macOS + Linux support (PTY via node-pty)
  • [x] Windows support (ConPTY via node-pty)
  • [x] Local mode (no tunnel)
  • [x] MS Dev Tunnel backend
  • [x] Tailscale backend (userspace networking)
  • [x] xterm-headless server-side state tracking
  • [x] Session reconnect with full terminal state replay
  • [x] Server-side health checks (HTTP ping every 10s)
  • [x] Auto-register on first start
  • [x] easy-service integration
  • [ ] E2E encryption
  • [ ] File transfer

License

MIT