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

@tsconfigdotjson/vibe-os

v0.7.0

Published

A coding desktop in the browser, on a box you own. Git worktrees per piece of work, terminals that survive a reload, and SSH that runs in the tab.

Readme

A coding desktop in the browser, on a box you own.

Switch between the git repos on a machine, spin up a worktree per piece of work, and open terminals into it, from anything with a browser.

CI License: MIT


Open the desktop and you get a project picker, a sidebar of workspaces, and windows you can drag around a snap grid. Every window is a dtach session in its workspace's worktree, so closing the tab and coming back tomorrow finds whatever was running still running.

Down the right is a rail of profiles, the roles you work as. QA Engineer, Backend Manager, whatever your work divides into. Each carries a colour, a harness with its settings, and a standing prompt. Click one and you get a window tinted in its colour with Claude already running in the worktree.

There is nothing to configure. No key to copy and paste, no authorized_keys to edit, no sshd_config change, and no root.

Contents


Quick start

Try it locally

docker run --rm -p 127.0.0.1:8080:80 -e VIBE_OS_NO_TOKEN=1 ghcr.io/tsconfigdotjson/vibe-os
open http://localhost:8080

A blank Debian box with sshd, dtach and git, the same shape as a fresh VPS. The token is off, so the port is on loopback only: a vibe-os with no token is a shell for anyone who can reach it. The image has no harness, so profiles open a shell; from a clone, docker compose up --build adds Claude Code.

Or set up a VPS

On a fresh Debian or Ubuntu box, as any user with sudo (or as root, which creates one):

curl -fsSL https://raw.githubusercontent.com/tsconfigdotjson/vibe-os/main/install.sh | sh
vibe-os setup                            # private: reached over your tailnet
vibe-os setup --domain box.example.com   # or public: HTTPS on a name pointing at the box

setup runs the same checks as doctor and offers to fix each one, printing every command before it runs it. Private puts it behind Tailscale, so only your tailnet can reach it. Public serves it to the internet with its own Let's Encrypt certificate and the token as the gate (On a public address). See Setup for each step.

For an agent with SSH access to the box, the prompt is one line:

Install vibe-os with curl -fsSL https://raw.githubusercontent.com/tsconfigdotjson/vibe-os/main/install.sh | sh, then run vibe-os setup --yes and show me its output.


Drive it from an agent (MCP)

vibe-os is also an MCP server, at /mcp on the same URL as the desktop. An agent in Claude Code, Codex, Cursor or any other MCP client can create workspaces, open windows as profiles, hand them prompts, wait for them to finish and read their answers.

It needs the URL and the server's token. On the box, the token is in ~/.vibe-os/config.json:

export VIBE_OS_TOKEN=$(sed -n 's/.*"token": *"\([^"]*\)".*/\1/p' ~/.vibe-os/config.json)

Then, for Claude Code:

claude mcp add --transport http vibe-os https://your-box.example.com/mcp \
  --header "Authorization: Bearer $VIBE_OS_TOKEN"

MCP has the setup for Codex, Cursor, VS Code, Windsurf, Gemini CLI and Claude Desktop, and the tools it offers. The token is a shell on the box: keep it out of anything that is shared or logged.


How it works

┌─────────────────┐                        ┌──────────────────┐        ┌──────┐
│     browser     │   wss://…/websocket    │  vibe-os (bun)   │  TCP   │ sshd │
│   ssh.wasm      │ ─────────────────────► │    :80 / :443    │ ─────► │  :22 │
│  private key    │                        │   byte pipe      │        │      │
│  in IndexedDB   │   POST /api/ssh/…      │   + SSH CA       │        │dtach │
└─────────────────┘ ─────────────────────► └──────────────────┘        └───▲──┘
                                                                           │
┌─────────────────┐                                                        │
│  your terminal  │   ssh -t … vibe-os attach quiet-amber-otter-1           │
│   ssh + dtach   │ ──────────────────────────────────────────────────────►─┘
└─────────────────┘

The SSH protocol runs inside the browser. Key exchange, authentication and channel multiplexing happen in a Go/WASM sandbox in the tab. The server is a byte pipe: it never sees plaintext and holds no credentials for your session.

vibe-os is its own short-lived certificate authority. On first start it generates an ed25519 CA and appends one cert-authority line to ~/.ssh/authorized_keys. Each window generates a keypair in the browser, keeps the private half in IndexedDB, and posts only the public half to be signed. Certificates last 12 hours. Revoking every browser that ever connected is deleting one line.

Windows survive because dtach owns them, not vibe-os. Each certificate carries a force-command that attaches to the window's dtach socket, creating it in the workspace's worktree if it is not there yet. Restarting the server, reloading the page and closing the laptop all leave the session running.

The bottom route in that diagram is the same session by a different door: your own ssh client, your own key, straight to sshd. See popping out.


Documentation

| | | | --- | --- | | Using it | projects, workspaces, profiles, prompts, popping a terminal out, the desktop and its shortcuts | | Harnesses | Hermes, Cursor, Codex and Pi, and adding your own | | Deploying on a VPS | what the box needs, setup, Tailscale or a public address, the firewall, memory, an always-on browser, updating | | Security | the token, what it gates, and what to put in front of it | | CLI reference | every command and flag | | API | driving workspaces and windows over HTTP | | MCP | the same, as MCP tools for Claude Code, Codex and Cursor | | Development | building, testing and releasing |

vibe-os hands out shell access to the machine it runs on. Treat access to it as equivalent to SSH access to the box, and read Security before exposing it anywhere.


Contributing

Issues and pull requests welcome. Before opening one:

bun run check     # lint, typecheck and tests, the same three CI runs

Tests live in test/ for the server and beside the code for the browser. Anything with logic worth trusting should arrive with some.

docs/gotchas.md lists the traps in this codebase that cost someone an afternoon. Worth a skim before changing the terminal or the session plumbing.

Comments in this repository explain why rather than what. If you undo a documented decision, update the reasoning with it.


License

MIT, see LICENSE. Bundles c2FmZQ/sshterm (MIT) and the packages listed in THIRD_PARTY_NOTICES.md. After changing dependencies, regenerate that file with bun run notices.