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

@fervon/launchpad

v1.3.0

Published

Local-first dashboard to discover, launch and monitor every dev project in a folder — auto-detected, no port clashes, live logs. Binds 127.0.0.1 only.

Readme

🛰️ Mission Control

npm License homepage

One folder, a dozen repos, one screen — no port collisions.

Point Mission Control at the folder where you keep your projects and press start. It auto-detects every dev project, infers how to launch each one from its own files, and runs them all at once on collision-free ports — with live logs, git status, and health in a single view. No cd rituals, no port-clash detective work, no stray node holding port 5173 from yesterday.

🔒 Local-only by design. Binds 127.0.0.1 (HTTP + WebSocket), never 0.0.0.0. No accounts, no telemetry, no phone-home.

Part of Fervon — a small studio of local-first developer tools.

⭐ If Mission Control saves you a single cd + port-clash hunt, give it a star — it's the fastest way to help it grow. Got a project it can't auto-detect, or an idea? Open an issue.

Why

If you keep a dozen projects in one folder, you know the dance: cd into each one, remember its dev command, discover two of them both want port 5173, kill the stray node that's still holding a port from yesterday. Mission Control replaces all of that with one screen.

Features

  • Zero-config auto-detection, polyglot — scans your projects folder and infers each project's type and dev command from its own files:
    • JS/TS — Vite (React / Vue / Svelte / SvelteKit / Solid / Preact), Next, Nuxt, Remix, Astro, Electron, Express / Fastify / Koa / hapi / Hono / NestJS, static sites, Telegram & Discord bots, CLIs, workspace monorepos, and backend/+frontend/ splits.
    • Python — FastAPI, Django, Flask. Go (go.mod), Rust (Cargo.toml), Deno (deno.json tasks). Docker Compose stacks are detected and labelled (not launched — see below).
  • Uses your package manager — the dev and install commands follow the project's lockfile: pnpm dev for pnpm-lock.yaml, yarn / bun run / npm run likewise. Mission Control never runs npm install inside a pnpm workspace.
  • Launch many at once, never a port clash — every project gets a unique port in a configurable range (default 4000–4099), injected at launch (PORT env + the right CLI flag per framework). Run five at the same time, all isolated.
  • Live logs streamed over WebSocket (ANSI-clean), with filter / follow / clear.
  • Git at a glance — branch, dirty count, ahead/behind, last commit.
  • Health — npm/PyPI published version + GitHub CI status (via gh), cached.
  • Friendly failures — missing node_modules? A one-click Install button. Missing env/token? A clear hint instead of a red wall.
  • Live re-scan — drop a new project folder in and it animates into the grid, and edit a project's manifest (or add a lockfile) and its card re-classifies itself. No restart, no Rescan button. Watching is filtered to the manifests that matter, so build output costs nothing.
  • Survives its own crash — if the dashboard is killed hard, your dev servers keep running; the next boot adopts the ones still holding their ports so you can stop them from the grid instead of hunting for a pid.
  • Clean process control — start/stop with a full process-tree kill on both platforms (taskkill /T /F on Windows; SIGTERM to the process group, then SIGKILL, on macOS/Linux), so nothing is left holding a port.

Quick start

Run it from the folder that holds your projects:

cd ~/code
npx @fervon/launchpad

Open http://127.0.0.1:7777. On first run it scans that folder, writes a .launchpad.json next to your projects (ports and per-project overrides live there — add it to your global gitignore if you like), and shows the grid. That's it. Nothing to configure, nothing installed globally.

npx @fervon/launchpad --port 7788      # dashboard on another port
npx @fervon/launchpad --root ~/work    # scan a different folder
npx @fervon/launchpad --help

From source

git clone https://github.com/JoniMartin27/launchpad
cd launchpad
npm install
npm run build      # build the web UI
npm start          # serve UI + API + WS on http://127.0.0.1:7777

A checkout is meant to live inside the folder it manages, and scans its parent — it excludes itself from the grid:

~/code/                     ← your projects root
├── project-a/
├── project-b/
└── launchpad/              ← clone here

Different projects folder? --root /path/to/code, or the env var MISSION_CONTROL_PROJECTS_ROOT, or settings.projectsRoot in the config file.

Port 7777 already taken? --port 7788, or MISSION_CONTROL_PORT=7788. Flags win over env vars, which win over the config file.

Mission Control excludes itself from the scan (by path, so the clone folder can be called anything), and never launches what it cannot cleanly stop: Docker Compose stacks are shown and labelled but have no Start button, because docker compose up leaves containers that a process-tree kill would not reclaim.

Dev mode (hot reload)

npm run dev        # Fastify (:7777) + Vite (:5180) with HMR

Tests

npm test           # 169 server tests (node:test) + 27 frontend tests (vitest)
npm run test:server
npm run test:web

How it works

| Module | Role | |---|---| | server/src/discovery.js | Scans the projects root, classifies each project generically (no hardcoded names), resolves unique ports. | | server/src/launcher.js | Spawns the dev command with the port injected, streams logs, tree-kills on stop. | | server/src/frameworks.js| Per-framework table: how to inject the port (env var + CLI flag). | | server/src/watcher.js | Debounced fs.watch on the root → live add/remove of projects. | | server/src/git.js · metrics.js | Git status and npm/PyPI/CI health, cached and non-blocking. |

See SPEC.md for the full REST + WebSocket contract and DESIGN.md for the UI design system.

Configuration

Discovery is hybrid: an automatic filesystem scan, unioned with per-project overrides in a machine-local config file — .launchpad.json in your projects folder when installed from npm, or config.json at the repo root in a checkout (git-ignored there; see config.example.json). Override it entirely with --config / MISSION_CONTROL_CONFIG. Edit it by hand or from the dashboard. Per project you can override:

| Field | Meaning | |---|---| | port | Pin the assigned port | | name | Display name | | command | Override the dev command | | portFlag / portEnv | How the port is passed (e.g. --port, PORT) | | env | Extra environment variables (${PORT} is substituted) | | hidden / runnable | Hide a card / mark it non-launchable | | cwd | Working directory | | autoRestart | Bring this project back up if it crashes (non-zero exit) while running. Off by default; there is a switch for it in the card drawer, and an armed card is marked in the grid. Bounded by settings.autoRestartMax (3) with a growing wait; never fires after you stop it, or for a start that never came up. | | registry | Where the published-version badge looks: { "kind": "npm"|"pypi"|"none", "name": "pkg" }. Only needed when the manifest cannot say it — e.g. a private workspace root whose published package is a member. |

Global settings live under settings (projectsRoot, dashboardPort, portRange, metricsTtlSec, readyRegex, autoScan, scanDepth, maxProjectWatchers, autoRestartMax, portlessGraceMs, editorCommand).

Projects in subfolders

Keep your work in code/work/* and code/personal/*? Mission Control scans one level by default, notices it found nothing, looks deeper on its own and says so in a banner — then remembers the depth that worked (settings.scanDepth, max 3) so the grid stays stable. Nested projects are named after their trail (work/api), so two folders both called api never collide.

A project folder is never descended into: a monorepo stays one card.

Getting to a project

Open a card and the drawer offers the three things you would otherwise cd for: your editor, the folder, and a terminal already in it. Set settings.editorCommand to whatever you use (code, subl, webstorm, nvim…); the file manager and terminal are chosen per platform.

Paths are taken from the catalog and passed to the tool as a separate argument with no shell involved, so a folder with a & in its name cannot run anything.

Bringing up a whole stack

Two buttons in the top bar act on what you can already see: ▶ Start N starts every startable project currently shown (respecting your search and filters, and skipping anything already up or waiting on an install), and ⏻ Stop all stops everything that is running.

For a fixed set — front end, API and database, say — name it in the config:

"profiles": {
  "stack": ["api", "web", "db"]
}
curl -X POST localhost:7777/api/batch/start -H 'content-type: application/json' -d '{"profile":"stack"}'

Batch responses are per project: one that cannot start never aborts the rest, and the answer says exactly what happened to each — started, already-running, not-runnable, failed with its reason. A partial batch comes back as HTTP 207, never a plain 200.

Requirements

  • Node 20+ (CI runs on Node 20 and 22). Optional, per ecosystem you actually use: git and the GitHub gh CLI for the git/CI panels; uv for Python (FastAPI / Django / Flask); go, cargo, deno, pnpm, yarn, bun for those projects. All degrade gracefully if absent — a missing toolchain shows up as a friendly needs-env card, not a crash.
  • Windows, macOS and Linux. CI runs the full suite on Windows and Linux, because process control differs per platform — the tree-kill test starts a real grandchild process on each and asserts it dies. Day-to-day development happens on Windows.

Security posture

Single-user, loopback-only. Every request is checked for a loopback remote address; the socket binds 127.0.0.1 exclusively. It launches processes you already have on disk with commands derived from those projects — treat it like running npm run dev yourself. See SECURITY.md for the threat model and how to report an issue, and SPEC.md §9.

Contributing

The single most useful thing you can send is a project it failed to detect: open a Project not detected issue with your manifest and folder layout. See CONTRIBUTING.md for the dev loop and house rules, and CHANGELOG.md for what has changed.

License

MIT