{"id":50556868,"url":"https://github.com/ntd4996/porthole","last_synced_at":"2026-06-04T08:00:33.162Z","repository":{"id":362421848,"uuid":"1258420429","full_name":"ntd4996/Porthole","owner":"ntd4996","description":"macOS menu bar app: see which dev ports are running, which project owns each, and which tunnels point where.","archived":false,"fork":false,"pushed_at":"2026-06-04T06:38:23.000Z","size":3033,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-04T07:10:12.143Z","etag":null,"topics":["cloudflare-tunnel","developer-tools","devtools","macos","menubar","ngrok","ports","swift","swiftui"],"latest_commit_sha":null,"homepage":"https://ntd4996.github.io/Porthole/","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ntd4996.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-03T15:03:06.000Z","updated_at":"2026-06-04T06:38:22.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ntd4996/Porthole","commit_stats":null,"previous_names":["ntd4996/porthole"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/ntd4996/Porthole","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ntd4996%2FPorthole","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ntd4996%2FPorthole/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ntd4996%2FPorthole/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ntd4996%2FPorthole/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ntd4996","download_url":"https://codeload.github.com/ntd4996/Porthole/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ntd4996%2FPorthole/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33895175,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-04T02:00:06.755Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cloudflare-tunnel","developer-tools","devtools","macos","menubar","ngrok","ports","swift","swiftui"],"created_at":"2026-06-04T08:00:32.601Z","updated_at":"2026-06-04T08:00:33.151Z","avatar_url":"https://github.com/ntd4996.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\u003cimg src=\"assets/icon-1024.png\" width=\"120\" alt=\"Porthole icon\" /\u003e\n\n# Porthole\n\n**See which dev ports are running, which project owns each one, and which tunnels point where, right from your menu bar.**\n\n[![CI](https://github.com/ntd4996/Porthole/actions/workflows/ci.yml/badge.svg)](https://github.com/ntd4996/Porthole/actions/workflows/ci.yml)\n[![Download](https://img.shields.io/github/v/release/ntd4996/Porthole?label=download\u0026color=0E7490)](https://github.com/ntd4996/Porthole/releases/latest)\n[![Platform](https://img.shields.io/badge/macOS-14%2B-blue)](https://github.com/ntd4996/Porthole/releases/latest)\n[![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)\n\n\u003cimg src=\"assets/hero.png\" width=\"640\" alt=\"Porthole popover\" /\u003e\n\n\u003c/div\u003e\n\n## What it does\n\nWhen you run a dozen dev servers across projects, `lsof -i` gets old fast. Porthole keeps a live list in your menu bar:\n\n- **Running dev ports** with the process behind each one (`vite`, `next`, `prisma`, `uvicorn`…).\n- **Which project owns the port**, resolved from the process working directory (git root / `package.json` / `go.mod` / `pyproject.toml`…), grouped per project.\n- **Tunnels pointing at a port**, detected from ngrok, Cloudflare Tunnel, Tailscale, and localtunnel, with the public URL one click away.\n- **Quick actions** per port: open `localhost:PORT` in the browser, copy the URL, or kill the process.\n- **Ignore list** to hide noisy system services (ControlCenter, rapportd, …) so you only watch real dev ports. Seeded with sensible defaults; fully editable.\n\n## Install\n\n### Homebrew (recommended)\n\n```bash\nbrew install --cask ntd4996/tap/porthole\n```\n\n### Direct download\n\nGrab the latest signed \u0026 notarized `.dmg` from the [releases page](https://github.com/ntd4996/Porthole/releases/latest), open it, and drag Porthole to Applications.\n\nPorthole lives in the menu bar (no Dock icon). Click the porthole icon to open the panel.\n\n## How it works\n\nPorthole shells out to standard tools and parses their output, no kernel extensions, no elevated privileges:\n\n- `lsof -nP -iTCP -sTCP:LISTEN` for listening sockets, and `lsof … -d cwd` to find each process's directory.\n- The ngrok local API (`127.0.0.1:4040`), the `cloudflared` / `lt` command lines, `~/.cloudflared/config.yml`, and `tailscale serve status` for tunnels. Public URLs are best-effort (Cloudflare quick-tunnel URLs are not always available).\n\nIt is non-sandboxed (required to spawn `lsof`/`ps`) and distributed as a notarized Developer ID build.\n\n## Build from source\n\n```bash\ngit clone https://github.com/ntd4996/Porthole.git\ncd Porthole\nswift build\nswift test\nswift run porthole          # run the menu bar app\n./scripts/build-app.sh      # produce build/Porthole.app\n```\n\nRequires macOS 14+ and a recent Swift toolchain. The detection logic lives in the `PortholeCore` target (pure, unit-tested); the SwiftUI menu bar UI lives in the `porthole` app target.\n\n## License\n\n[MIT](LICENSE) © Dat Nguyen\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fntd4996%2Fporthole","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fntd4996%2Fporthole","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fntd4996%2Fporthole/lists"}